Q 语言 用 JWT 实现 API 接口的身份认证与授权

Q阿木 发布于 1 天前 2 次阅读


JWT 实现API接口的身份认证与授权

随着互联网技术的不断发展,API(应用程序编程接口)已成为现代软件开发中不可或缺的一部分。为了确保API的安全性,身份认证与授权机制变得尤为重要。JWT(JSON Web Token)是一种轻量级的安全令牌,常用于在网络上安全地传输信息。本文将围绕JWT,探讨其在API接口身份认证与授权中的应用。

JWT是一种基于JSON的开放标准(RFC 7519),用于在各方之间安全地传输信息。它包含一个签名后的JSON对象,通常用于身份认证和授权。JWT的主要优点包括:

- 无需服务器存储用户信息,减轻服务器负担;
- 支持跨域请求;
- 适用于分布式系统;
- 可扩展性强。

JWT工作原理

JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。

1. 头部:描述JWT的类型和签名算法,通常包含以下字段:
- `alg`:签名算法,如HS256、RS256等;
- `typ`:JWT类型,通常为`JWT`。

2. 载荷:包含用户信息,如用户ID、角色、权限等。载荷通常包含以下字段:
- `iss`:发行者;
- `exp`:过期时间;
- `iat`:签发时间;
- `sub`:主题,通常是用户ID;
- `aud`:受众,通常是API接口;
- `nbf`:不可使用之前的时间;
- `jti`:JWT的唯一标识。

3. 签名:使用头部中指定的算法对头部和载荷进行签名,生成签名。签名用于验证JWT的完整性和真实性。

JWT在API接口身份认证与授权中的应用

1. 用户登录

当用户登录系统时,服务器验证用户名和密码。验证成功后,服务器生成JWT,并将其发送给客户端。客户端在后续请求中携带该JWT,以证明其身份。

python
from flask import Flask, request, jsonify
import jwt
import datetime

app = Flask(__name__)
SECRET_KEY = 'your_secret_key'

@app.route('/login', methods=['POST'])
def login():
username = request.json['username']
password = request.json['password']
验证用户名和密码
if username == 'admin' and password == 'admin':
payload = {
'sub': username,
'iat': datetime.datetime.utcnow(),
'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1)
}
token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
return jsonify({'token': token})
else:
return jsonify({'error': 'Invalid username or password'}), 401

if __name__ == '__main__':
app.run()

2. 用户授权

在用户登录成功后,服务器根据用户角色和权限生成JWT。客户端在请求需要授权的API接口时,携带JWT进行身份验证。

python
from flask import Flask, request, jsonify
import jwt
import datetime

app = Flask(__name__)
SECRET_KEY = 'your_secret_key'

@app.route('/api/protected', methods=['GET'])
def protected():
token = request.headers.get('Authorization')
if not token:
return jsonify({'error': 'Authorization token is missing'}), 401
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
except jwt.ExpiredSignatureError:
return jsonify({'error': 'Token has expired'}), 401
except jwt.InvalidTokenError:
return jsonify({'error': 'Invalid token'}), 401
根据用户角色和权限进行授权
if payload['sub'] == 'admin':
return jsonify({'message': 'Access granted'})
else:
return jsonify({'error': 'Access denied'}), 403

if __name__ == '__main__':
app.run()

3. JWT刷新

JWT具有过期时间,当过期后,客户端需要重新获取新的JWT。为了简化流程,可以使用JWT刷新机制。

python
from flask import Flask, request, jsonify
import jwt
import datetime

app = Flask(__name__)
SECRET_KEY = 'your_secret_key'

@app.route('/login', methods=['POST'])
def login():
username = request.json['username']
password = request.json['password']
验证用户名和密码
if username == 'admin' and password == 'admin':
payload = {
'sub': username,
'iat': datetime.datetime.utcnow(),
'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1)
}
token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
refresh_token = jwt.encode(payload, SECRET_KEY, algorithm='HS256', options={'exp': datetime.datetime.utcnow() + datetime.timedelta(days=1)})
return jsonify({'token': token, 'refresh_token': refresh_token})
else:
return jsonify({'error': 'Invalid username or password'}), 401

@app.route('/refresh', methods=['POST'])
def refresh():
refresh_token = request.json['refresh_token']
try:
payload = jwt.decode(refresh_token, SECRET_KEY, algorithms=['HS256'])
except jwt.ExpiredSignatureError:
return jsonify({'error': 'Refresh token has expired'}), 401
except jwt.InvalidTokenError:
return jsonify({'error': 'Invalid refresh token'}), 401
生成新的JWT
new_token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
return jsonify({'token': new_token})

if __name__ == '__main__':
app.run()

总结

JWT在API接口身份认证与授权中具有广泛的应用。相信您已经对JWT有了更深入的了解。在实际应用中,可以根据需求选择合适的JWT实现方案,确保API接口的安全性。