Python 后端基础(四):JWT 登录鉴权流程从零讲明白,Token 到底怎么用
JWT 是前后端分离项目里非常常见的登录鉴权方案。本文从用户登录、签发 Token、请求携带 Token、后端解析 Token、权限控制和过期处理讲起,适合 Python 后端初学者和秋招面试复习。
【一、认证和授权先区分清楚】
很多人学 JWT 时会把认证和授权混在一起。
- 认证 Authentication:确认你是谁。比如登录时校验账号密码。
- 授权 Authorization:确认你能做什么。比如普通用户不能访问管理员接口。
登录成功只能说明你是某个用户,不代表你有所有权限。
【二、JWT 是什么】
JWT 全称 JSON Web Token,是一种把用户身份信息编码到 Token 里的格式。
一个 JWT 通常长这样:
xxxxx.yyyyy.zzzzz
它由三部分组成:
Header.Payload.Signature
- Header:说明算法和 token 类型。
- Payload:保存用户信息和过期时间等声明。
- Signature:签名,用来防止 token 被篡改。
注意:JWT 默认只是 Base64Url 编码,不是加密。Payload 里的内容不要放密码、身份证、手机号等敏感信息。
【三、JWT 登录流程】
典型流程:
1. 用户提交账号密码
2. 后端校验账号密码
3. 校验成功后生成 JWT
4. 前端保存 JWT
5. 前端后续请求在 Authorization 请求头携带 JWT
6. 后端验证 JWT 签名和过期时间
7. 验证通过后识别当前用户
请求头一般这样写:
http
Authorization: Bearer eyJhbGciOi...
`Bearer` 表示这是一种令牌认证方式。
【四、JWT 里面一般放什么】
Payload 常见字段:
{
"sub": "1001",
"username": "tom",
"role": "admin",
"exp": 1790000000
}
说明:
- `sub`:subject,通常放用户 id。
- `username`:用户名,非敏感信息。
- `role`:角色,可以放,但权限复杂时不建议只依赖它。
- `exp`:过期时间。
不要放:
- 密码
- 密码 hash
- 身份证
- 手机号
- API Key
- 大段业务数据
【五、JWT 和 Session 的区别】
| 对比 | Session | JWT |
|---|---|---|
| 登录状态存在哪里 | 服务端 | 客户端保存 Token |
| 服务端是否需要查会话 | 通常需要 | 通常不需要 |
| 适合场景 | 传统 Web | 前后端分离、移动端、微服务 |
| 主动失效 | 容易 | 相对麻烦 |
| 扩展性 | 依赖共享 session | 更容易跨服务 |
JWT 的优势是无状态,但无状态也意味着服务端不保存 token 状态。要想主动踢下线、修改密码后失效旧 token,通常需要引入黑名单、版本号、短 token + refresh token 等机制。
【六、FastAPI 示例】
示例只演示核心思想,真实项目要使用成熟库,例如 `python-jose` 或 `PyJWT`。
from fastapi import FastAPI, Header, HTTPException
app = FastAPI()
fake_token_user = {
"valid-token": {"id": 1, "username": "tom", "role": "user"}
}
@app.post("/login")
def login(username: str, password: str):
if username == "tom" and password == "123456":
return {"access_token": "valid-token", "token_type": "bearer"}
raise HTTPException(status_code=401, detail="用户名或密码错误")
@app.get("/me")
def me(authorization: str = Header(default="")):
if not authorization.startswith("Bearer "):
raise HTTPException(status_code=401, detail="未登录")
token = authorization.replace("Bearer ", "")
user = fake_token_user.get(token)
if not user:
raise HTTPException(status_code=401, detail="token 无效")
return user
真实项目里不要用固定字符串 token,要使用签名算法生成 JWT。
【七、Access Token 和 Refresh Token】
更规范的登录系统通常会拆成两个 token:
- Access Token:有效期短,比如 30 分钟,用来访问接口。
- Refresh Token:有效期长,比如 7 天或 30 天,用来刷新 Access Token。
这样做的好处是:即使 Access Token 泄露,风险时间也比较短。
【八、权限控制怎么做】
认证通过后,还要判断权限。
例子:
普通用户:只能看自己的订单
管理员:可以看所有订单
作者:可以编辑自己的文章
超级管理员:可以管理角色和权限
项目里常见模型:
- 用户 user
- 角色 role
- 权限 permission
- 用户角色关系 user_role
- 角色权限关系 role_permission
简单项目可以先用角色控制,复杂项目再做 RBAC。
【九、常见安全问题】
- JWT secret 太短,容易被爆破。
- token 永不过期。
- 把敏感数据放进 payload。
- 前端把 token 存在不安全位置,又没有配合 XSS 防护。
- 后端只解析 token,不校验签名。
- 修改密码后旧 token 仍然可用。
更多推荐
所有评论(0)