drf-jwt使用

发布时间 2023-09-08 19:01:53作者: Maverick-Lucky

一、jwt介绍和构成

1. 介绍

 jwt:Json Web Token,Web方向的Token认证方案

  在用户注册或登录之后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证(token串)。我们不再使用session认证机制,而使用Json Web Token(本质就是token)认证机制。

  Json Web Token:JWT用在我们前后端做登录认证,如果登录了,就携带token过来,如果没登录,就不携带了,后端通过验证token的准确性,确定是谁访问我们。

2. 构成

JWT就是一段字符串,由三段信息构成的,将这三段信息文本用 .连接一起就构成了Jwt字符串。就像这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 类似于飞机上承载的物品),第三部分是签证(signature)。

2.1 头(header)

一般放公司信息,加密方式(没放秘钥)

jwt的头部承载两部分信息:

  • 声明类型,这里是jwt
  • 声明加密的算法 通常直接使用 HMAC SHA256

完整的头部就像下面这样的JSON

 2.2 荷载(payload)

一般存放:当前用户信息:用户名,用户id,token过期时间

2.3 签名(signature)

签名由头(base64加密后)和荷载(base64加密后),在通过加密得到的字符串。

二、 jwt签发与认证

以后使用jwt,最核心的就是写两个地方

  - 签发(登录接口)

    - 登录接口,登录成功,签发token(三段式)

    - header,用base64编码,

    - payload,用base64编码,

    - signature,使用加密方式:用md5把header和payload加密,生成签名,然后再用base64编码

-认证(认证类)
  -用户携带token过来,认证
  -取出第一部分header
  -取出第二部分 payload
  -使用之前同样的加密算法(密码),得到新前面
  -跟token的第三部分比较,如果一样,表示没有被窜改,顺利继续往下走,返回两个值
  -如果被篡改了,抛异常

 

drf项目的jwt认证开发流程(重点)

"""
1)用账号密码访问登录接口,登录接口逻辑中调用 签发token 算法,得到token,返回给客户端,客户端自己存到cookies中

2)校验token的算法应该写在认证类中(在认证类中调用),全局配置给认证组件,所有视图类请求,都会进行认证校验,所以请求带了token,就会反解出user对象,在视图类中用request.user就能访问登录的用户

注:登录接口需要做 认证 + 权限 两个局部禁用
"""

 

补充:base64编码

1. base64编码的作用(使用场景): 

  1. token串使用base64编码

  2. 互联网中前后端数据交互,可以使用base64编码

  3. 图片二进制可以使用base64编码传递

2. base64 的编码和解码(字符串):是对字符串进行操作,要将字符串转成bytes类型

编码:

 解码:

 三、drf-jwt使用

可以自己写,也可以使用第三方的

  -django-rest-framework-jwt:有点老

  -djangorestframework-simplejwt:新的-自己写:https://gitee.com/liuqingzheng/rbac_manager/blob/master/libs/lqz_jwt/token.py

下载:pip install djangorestframework-jwt

1.django-rest-framework-jwt快速使用

签发:默认使用auth的user表签发,登录接口不需要自己写,人家帮我们写了

  在总路由文件中进行配置,

  from rest_framwork_jwt.views import obtain_jwt_token #这个就是登录接口

  urlpatterns = [path('login/', obtain_jwt_token),]

认证:实际上就是认证类

  视图类上,配置认证类和权限类

authentication_classes = [JSONWebTokenAuthentication]
permission_classes = [IsAuthenticated]

2. 定制签发返回格式

我们可以自定义返回结果,

1.先写一个函数:

def jwt_response_payload_handler(token, user=None, request=None):
    return {
        'status': 100,
        'msg': '登录成功', 
        'token': token, 
        'username': user.username
    }

2. 在配置文件中配置

 源码分析

为什么路由这样配置了,就会有个登录接口?

path('login/', obtain_jwt_token)

obtain_jwt_token的本质:ObtainJsonWebToken.as_view()

ObtainJSONWebToken源码:

class ObtainJSONWebToken(JSONWebTokenAPIView):

serializer_class = JSONWebTokenSerializer

# 向login发送post请求,ObtainJSONWebToken一定有个post方法

# 在父类中:JSONWebTokenAPIView post
-登录走的是JSONWebTokenAPIView的post,签发token 是在序列化类中
-签发完token执行了,咱们写的jwt_response_payload_handler,所以才能定制返回格式