JWT 登录鉴权全流程完整步骤
作者:Aerkui
JWT是一种用于在各方之间安全传输信息的开放标准,JWT的优势在于无状态、分布式支持和简单性,本文给大家介绍JWT登录鉴权全流程,感兴趣的朋友跟随小编一起看看吧
一、什么是 JWT?
JWT(JSON Web Token) 是一种开放标准(RFC 7519),用于在各方之间安全地传输信息。它常被用作用户登录后的身份凭证(替代传统的 Session)。
JWT 长什么样?
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJ1c2VyX2lkIjoxMjMsImV4cCI6MTcwMDAwMDAwMH0. HMACSHA256(base64UrlEncode(header)+'.'+base64UrlEncode(payload), secret)
由三部分组成,用 . 连接:
- Header(头部):算法和类型
- Payload(载荷):用户数据 + 过期时间等
- Signature(签名):防篡改的关键
二、JWT 登录鉴权完整流程
📌 场景假设
- 用户:
alice - 密码:
123456 - 后端服务:提供
/login和受保护的/profile接口
✅ 步骤 1:用户提交账号密码(登录)
POST /login
Content-Type: application/json
{
"username": "alice",
"password": "123456"
}🔒 注意:密码应通过 HTTPS 传输!明文密码绝不应在日志或前端存储。
✅ 步骤 2:服务端验证账号密码
# 伪代码(Python + Flask)
from werkzeug.security import check_password_hash
@app.route('/login', methods=['POST'])
def login():
data = request.json
user = User.query.filter_by(username=data['username']).first()
if not user or not check_password_hash(user.password_hash, data['password']):
return jsonify({"error": "用户名或密码错误"}), 401
# 验证通过,生成 JWT
token = generate_jwt(user_id=user.id)
return jsonify({"token": token})⚠️ 安全提示:
- 密码必须加盐哈希存储(如 bcrypt、scrypt)
- 失败时不要区分“用户不存在”还是“密码错误”,防止枚举攻击
✅ 步骤 3:服务端生成 JWT 并返回
import jwt
import datetime
def generate_jwt(user_id):
payload = {
'user_id': user_id,
'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=2), # 2小时过期
'iat': datetime.datetime.utcnow() # 签发时间
}
secret = 'your_strong_secret_key' # 必须保密!建议从环境变量读取
return jwt.encode(payload, secret, algorithm='HS256')📝 Payload 常见字段(Claims):
sub:主题(如用户ID)exp:过期时间(必须设置!)iat:签发时间jti:JWT ID(用于黑名单)
✅ 步骤 4:前端保存 Token
// 登录成功后
localStorage.setItem('token', response.data.token);
// 后续请求携带 Token
fetch('/profile', {
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('token')
}
})💡 存储建议:
- 短期 Token:可存
localStorage(注意 XSS 风险) - 高安全场景:存
HttpOnly Cookie(防 XSS,但需防 CSRF)
✅ 步骤 5:访问受保护接口(携带 Token)
GET /profile Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxxx
✅ 步骤 6:服务端验证 JWT
@app.route('/profile')
def profile():
auth_header = request.headers.get('Authorization')
if not auth_header or not auth_header.startswith('Bearer '):
return jsonify({"error": "缺少 Token"}), 401
token = auth_header.split(' ')[1]
try:
payload = jwt.decode(token, 'your_strong_secret_key', algorithms=['HS256'])
user_id = payload['user_id']
user = User.query.get(user_id)
return jsonify({"username": user.username})
except jwt.ExpiredSignatureError:
return jsonify({"error": "Token 已过期"}), 401
except jwt.InvalidTokenError:
return jsonify({"error": "无效 Token"}), 401✅ 验证内容:
- 签名是否合法(防篡改)
- 是否过期(
exp) - 用户是否存在(防删除账号后仍能访问)
三、JWT 的优势 vs 传统 Session
| 特性 | JWT(无状态) | Session(有状态) |
|---|---|---|
| 服务器存储 | 不需要存 Token | 需要存 Session(内存/Redis) |
| 扩展性 | 天然支持分布式 | 需共享 Session 存储 |
| 跨域支持 | 简单(Header 携带) | 复杂(需处理 Cookie 跨域) |
| 登出控制 | 困难(除非用黑名单) | 简单(删 Session 即可) |
🧩 结论:
- 小型项目、API 服务 → 推荐 JWT
- 需要强登出控制、高安全性 → 考虑 Session + Redis
四、安全加固建议(必看!)
1. 使用强密钥
# .env JWT_SECRET=your_very_long_random_string_32_chars_or_more!
2. 设置合理过期时间
- Access Token:15分钟 ~ 2小时
- 刷新 Token(Refresh Token):7天(存数据库,可吊销)
3. 敏感操作二次验证
- 修改密码、支付等操作,即使有 Token 也要求重新输密码
4. 防止 Token 泄露
- 前端避免打印 Token 到 console
- 后端日志不要记录 Authorization Header
5. 考虑使用 JTI + 黑名单(实现登出)
# 登出时将 jti 加入 Redis 黑名单(有效期 = token 剩余时间)
redis.setex(f"blacklist:{payload['jti']}", ttl, "1")
# 验证时检查黑名单
if redis.get(f"blacklist:{payload['jti']}"):
raise Exception("Token 已失效")五、常见误区
❌ 误区1:JWT 是加密的
→ 错!JWT 默认是签名(Signature),不是加密(Encryption)。Payload 可被 Base64 解码!
✅ 敏感信息(如手机号)不要放 JWT!
❌ 误区2:Token 越长越好
→ 过长的 Token 会增加网络开销,且可能被代理截断
❌ 误区3:用了 JWT 就绝对安全
→ 安全取决于整体设计:HTTPS、密钥管理、输入校验缺一不可
六、总结:JWT 登录鉴权核心要点
- 登录 → 验证账号密码 → 生成带过期时间的 JWT
- 请求 → 前端在 Header 中携带
Authorization: Bearer <token> - 鉴权 → 后端验证签名 + 过期时间 + 用户状态
- 安全 → 强密钥、短有效期、不存敏感信息、配合 HTTPS
🌟 记住:JWT 是工具,不是银弹。理解其原理,才能用得安全又高效。
附:快速上手资源
- Python:
PyJWT库
到此这篇关于JWT 登录鉴权全流程详解的文章就介绍到这了,更多相关JWT 登录鉴权内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
