共计 1583 个字符,预计需要花费 4 分钟才能阅读完成。
JWT(Json Web Token): 是目前最流行的跨域身份验证解决方案。此前我们使用的身份验证方式都是基于 Session: 这种方式并没有什么不妥,但其实这里有三个缺点:
Session 一般存储在 redis 中,而 redis 数据保存在内存中,随着用户的增多,内存消耗太大。
扩展性不好,用户每次验证都需要请求 session 服务器,增大了负载均衡能力,应用扩展受限。
因为是基于 cookie 来进行用户识别的, cookie 如果被截获,用户就会很容易受到跨站请求伪造的攻击。
所以,我们需要一种既能实现相同要求并且还要比 session 存储更有效的身份验证方式。
JWT 通过一种加密的方式,将加密后的数据保存返回给用户本地进行保存,我们称为 token 数据。其数据由三部分组成:
1、header 声明类型和加密的算法:
{
‘typ’: ‘JWT’, #固定值
‘alg’: ‘HS256’ #加密算法
}
2、payload 负载这是有效信息的存放地方,其分为三部分:标准中注册的声明、公共声明、私有声明 (用户信息) 标准中的注册声明(有需要在使用,不强制使用):iss: jwt 签发者 sub: jwt 所面向的用户 aud: 接收 jwt 的一方 exp: jwt 的过期时间,这个过期时间必须要大于签发时间 nbf: 定义在什么时间之前,该 jwt 都是不可用的.iat: jwt 的签发时间 jti: jwt 的唯一身份标识,主要用来作为一次性 token, 从而回避重放攻击。公共声明:公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息. 私有声明:
{
“name”: “jim”,
“id”: “111111”,
“admin”: true
}
3、signature 签名需要 base64 加密后的 header 和 base64 加密后的 payload 使用. 连接组成的字符串,然后通过 header 中声明的加密方式进行加盐 secret 组合加密,然后就构成了 jwt 的第三部分。由于 base64 是对称加密算法,所以可以轻松解密:因此我们在负载部分不要将私密信息放置在里面,只需要把能验证唯一的标识信息添加就可以了。有关 base64, 请参考:https://www.liaoxuefeng.com/w… 由于目前在学习 DRF,所以我介绍一下怎样在 DRF 项目中使用 JWT 进行身份验证:安装 djangorestframework-jwt:
pip install djangorestframework-jwt
添加 jwt 认证类:
REST_FRAMEWORK = {
‘DEFAULT_PERMISSION_CLASSES’: (
‘rest_framework.permissions.IsAuthenticated’,
),
‘DEFAULT_AUTHENTICATION_CLASSES’: (
‘rest_framework_jwt.authentication.JSONWebTokenAuthentication’,
‘rest_framework.authentication.SessionAuthentication’,
‘rest_framework.authentication.BasicAuthentication’,
),
}
添加 jwt 路由用于生成 token:
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
url(r’^ 自己的路由 /’, obtain_jwt_token),
]
然后我们就可以通过自己添加的路由并通过 post 添加 username 和 password 来获取到 token 了,在进行访问页面的时候我们只需要在请求头中添加一个:Authorization: JWT <your_token>,就可以得到验证了。
本文参考:https://lion1ou.win/2017/01/18/