JWT(JSON Web Token)的认证过程
JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用环境间传递声明。它通过一个简洁的方式来实现用户身份的认证和信息的安全传输。下面我们将详细探讨 JWT 的认证过程。
1. 用户登录
用户在客户端输入用户名和密码,发送请求到服务器进行身份验证。
// 示例:用户登录请求
fetch('/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ username: 'user', password: 'pass' }),
});
2. 服务器验证用户身份
服务器收到请求后,验证用户提供的凭证(用户名和密码)。如果验证通过,服务器将生成一个 JWT。
# 示例:Python 伪代码
def login(username, password):
user = authenticate(username, password)
if user:
token = jwt.encode({'user_id': user.id}, 'secret', algorithm='HS256')
return token
3. 返回 JWT
服务器将生成的 JWT 返回给客户端。JWT 通常由三部分组成:头部(Header)、有效载荷(Payload)和签名(Signature)。
{
"header": {
"alg": "HS256",
"typ": "JWT"
},
"payload": {
"user_id": 123,
"exp": 1622559600
},
"signature": "abc123"
}
4. 客户端存储 JWT
客户端接收到 JWT 后,通常将其存储在本地存储(localStorage)或会话存储(sessionStorage)中,以便后续请求使用。
// 存储 JWT
localStorage.setItem('token', jwtToken);
5. 发送带 JWT 的请求
在后续的请求中,客户端将 JWT 作为 Authorization 头的一部分发送给服务器。
// 示例:发送带 JWT 的请求
fetch('/api/protected', {
method: 'GET',
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`,
},
});
6. 服务器验证 JWT
服务器接收到带有 JWT 的请求后,首先验证该 JWT 的有效性,包括签名、过期时间等。
# 示例:Python 伪代码
def protected_route(request):
token = request.headers.get('Authorization').split()[1]
try:
payload = jwt.decode(token, 'secret', algorithms=['HS256'])
user_id = payload['user_id']
# 继续处理请求
except jwt.ExpiredSignatureError:
return {"error": "Token expired"}, 401
except jwt.InvalidTokenError:
return {"error": "Invalid token"}, 401
7. 访问受保护的资源
如果 JWT 验证通过,服务器将允许用户访问受保护的资源。
# 示例:访问受保护资源
def protected_resource(user_id):
return {"data": "This is protected data for user {}".format(user_id)}
8. 过期和刷新
JWT 通常会设置过期时间,客户端需要在过期前进行刷新。刷新时可以发送请求,服务器返回一个新的 JWT。
// 示例:刷新 JWT
fetch('/api/refresh', {
method: 'POST',
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`,
},
});
9. 退出登录
当用户选择退出登录时,客户端可以简单地删除存储的 JWT,以阻止进一步的访问。
// 示例:退出登录
localStorage.removeItem('token');
总结
JWT 是一种轻量级的认证机制,适用于现代 Web 应用。通过上述步骤,客户端和服务器可以有效地进行身份验证和信息交换。JWT 的优点包括无状态性、跨域支持和易于扩展,但在使用时也要注意安全性,如保护密钥、使用 HTTPS 等。