JWT原理和简单应用

40次阅读

共计 2648 个字符,预计需要花费 7 分钟才能阅读完成。

JWT 认证登录
最近在做一个审核系统,后台登录用到 JWT 登录认证,在此主要做个总结
JWT 是什么
Json web token (JWT), 根据官网的定义,是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准. 该 token 被设计为紧凑且安全的,特别适用于分布式站点的单点登录场景。JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该 token 也可直接被用于认证,也可被加密。
为什么使用 JWT
此处主要和传统的 session 作对比,传统的 session 在服务器端需要保存一些登录信息,通常是在内存中,在后端服务器是集群等分布式的情况下,其他主机没有保存这些信息,所以都需要通过一个固定的主机进行验证,如果用户量大,在认证这个点上容易形成瓶颈,是应用不易拓展。
JWT 原理
JWT 由三个部分组成,用点号分割,看起来像是这样,JWT token 本身没有空格换行等,下面是为了美观处理了下
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
eyJpc3MiOiJsYWJzX3B1cmlmaWVyLWFwaS1wYW5lbCIsImlhdCI6MTU1Mjk3NTg3OCwiZXhwIjoxNTU1NTY3ODc4LCJhdWQiOiJodHRwOi8vZmYtbGFic19wdXJpZmllci1hcGktdGVzdC5mZW5kYS5pby9wcm9kL3YxL2F1dGgvand0Iiwic3ViIjoiMTUwMTM4NTYxMTg4NDcwNCIsInNjb3BlcyI6WyJyZWdpc3RlciIsIm9wZW4iLCJsb2dpbiIsInBhbmVsIl19.
m0HD1SUd30TWKuDQImwjIl9a-oWJreG7tKVzuGVh7e4
1. 头部 (Header)
Header 部分是一个 json,描述 JWT 的元数据,通常是下面这样
{
“alg”: “HS256”,
“typ”: “JWT”
}
alg 表示签名使用的的算法,默认是 HMAC SHA256,写成 HS256,tye 表示这个 token 的类型,JWT token 统一使用 JWT,上面这段 Header 生成的 token 是
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
2. 负载 (Payload)
官方规定了 7 个字段,解释如下

iss: 签发人,可以填写生成这个 token 的 ID 等等,可选参数
sub: 该 JWT 所面向的客户,可以存储用户的 account_id 等等,可选
aud:该 JWTtoken 的接收方,可以填写生成这个 token 的接口 URL,但是不强制,可选
exp: 过期时间,时间戳,整数,可选参数
iat:生成 token 的时间,unix 时间,时间戳,可选参数
nbf(Not Before): 表示该 token 在此时间前不可用,验证不通过的意思,可选
jti: JWT ID, 主要用来生成一次性 token,可选的参数

除了官方之外,我们还可以定义一部分自定义字段,但是考虑到 BASE64 是可逆的,所以不要放入敏感信息下面是一个例子;
{
“iss”: “labs_purifier-api-panel”,
“iat”: 1552975878,
“exp”: 1555567878,
“aud”: “http://ff-labs_purifier-api-test.fenda.io/prod/v1/auth/jwt”,
“sub”: “1501385611884704”,
“scopes”: [
“register”,
“open”,
“login”,
“panel”
]
}
上面这个 Payload,经过 BASE64 加密后,生成的 token 是
eyJpc3MiOiJsYWJzX3B1cmlmaWVyLWFwaS1wYW5lbCIsImlhdCI6MTU1Mjk3NTg3OCwiZXhwIjoxNTU1NTY3ODc4LCJhdWQiOiJodHRwOi8vZmYtbGFic19wdXJpZmllci1hcGktdGVzdC5mZW5kYS5pby9wcm9kL3YxL2F1dGgvand0Iiwic3ViIjoiMTUwMTM4NTYxMTg4NDcwNCIsInNjb3BlcyI6WyJyZWdpc3RlciIsIm9wZW4iLCJsb2dpbiIsInBhbmVsIl19
3. 签名 (Signature)
Signature 是对前面两部分生成的两段 token 的加密,使用的加密方式是 Header 里面指定的,此处是 HS256,此时,需要一个秘钥,不可以泄露,大致过程如下:
HMACSHA256(
base64UrlEncode(header) + “.” +
base64UrlEncode(payload),
secret)
JWT 的使用
JWT token 一般放在请求头里面,当然也可以放在 cookie 里面,但是放在 cookie 里面不可以跨域,例如:
Authorization: Bearer <token>
JWT 在 Python 中的简单生成和验证
jwt 库
生成 token
def create_token():
payload={
“iss”: “labs_purifier-api-panel”,
“iat”: 1552975878,
“exp”: 1555567878,
“aud”: Config.AUDIENCE,
“sub”: “1501385611884704”,
“scopes”: [
“register”,
“open”,
“login”,
“panel”
]
}
token = jwt.encode(payload, Config.SECRET_KEY, algorithm=’HS256′)
return True, {‘access_token’: token}
验证 token
def verify_jwt_token(token):
try:
payload = jwt.decode(token, Config.SECRET_KEY,
audience=Config.AUDIENCE,
algorithms=[‘HS256’])
except (ExpiredSignatureError, DecodeError):
return False, token
if payload:
return True, jwt_model
需要注意的是,如果在生成的时候,加上了 aud 参数,验证的时候也要用上 audience 参数,并且值必须一样

正文完
 0