认证组件、权限组件、drf-jwt框架、jwt认证算法

一、认证组件

1)认证规则
2)如何自定义认证类
3)我们一般不需要自定义认证类,在settings中全局配置第三方 jwt 认证组件提供的认证类即可

 

2)自定义认证类

1)自定义认证类,继承 BaseAuthentication 类
2)必须重写 authenticate(self, request) 方法
没有认证信息,返回None:匿名用户(游客) => 匿名用户request.user也有值,就是"匿名对象(Anonymous)"
有认证信息,且通过,返回(user, token):合法用户 => user对象会存到request.user中
有认证信息,不通过,抛异常:非法用户


settings文件中:全局配置认证组件

 

 

二、权限组件

1)权限规则
2)如何自定义权限类
3)我们一般在视图类中局部配置drf提供的权限类,但是也会自定义权限类完成局部配置

2)自定义权限类

1)自定义权限类,继承 BasePermission 类
2)必须重写 has_permission(self, request, view): 方法
设置权限条件,条件通过,返回True:有权限
设置权限条件,条件失败,返回False:有权限

3)drf提供的权限类:
AllowAny:匿名与合法用户都可以
IsAuthenticated:必须登录,只有合法用户可以
IsAdminUser:必须是admin后台用户
IsAuthenticatedOrReadOnly:匿名只读,合法用户无限制

views文件中:局部配置权限组件


 

 

 

 

三、基于session的认证

 

 

 

 

 

 

 

四、基于jwt(json web token)认证

 

 

 

  jwt认证算法:签发与校验

1)jwt分三段式:头.体.签名 (head.payload.sgin)
2)头和体是可逆加密,让服务器可以反解出user对象;签名是不可逆加密,保证整个token的安全性的
3)头体签名三部分,都是采用json格式的字符串,进行加密,可逆加密一般采用base64算法,不可逆加密一般采用hash(md5)算法
4)头中的内容是基本信息:公司信息、项目组信息、token采用的加密方式信息
{
"company": "公司信息",
...
}
5)体中的内容是关键信息:用户主键、用户名、签发时客户端信息(设备号、地址)、过期时间
{
"user_id": 1,
...
}
6)签名中的内容时安全信息:头的加密结果 + 体的加密结果 + 服务器不对外公开的安全码 进行md5加密
{
"head": "头的加密字符串",
"payload": "体的加密字符串",
"secret_key": "安全码"
}

1、签发:根据登录请求提交来的 账号 + 密码 + 设备信息 签发 token

1)用基本信息存储json字典,采用base64算法加密得到 头字符串
2)用关键信息存储json字典,采用base64算法加密得到 体字符串
3)用头、体加密字符串再加安全码信息存储json字典,采用hash md5算法加密得到 签名字符串

账号密码就能根据User表得到user对象,形成的三段字符串用 . 拼接成token返回给前台

2、校验:根据客户端带token的请求 反解出 user 对象

1)将token按 . 拆分为三段字符串,第一段 头加密字符串 一般不需要做任何处理
2)第二段 体加密字符串,要反解出用户主键,通过主键从User表中就能得到登录用户,过期时间和设备信息都是安全信息,确保token没过期,且时同一设备来的
3)再用 第一段 + 第二段 + 服务器安全码 不可逆md5加密,与第三段 签名字符串 进行碰撞校验,通过后才能代表第二段校验得到的user对象就是合法的登录用户

drf项目的jwt认证开发流程

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

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

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

五、drf-jwt框架基本使用

1、安装(终端)
>: pip install djangorestframework-jwt
2、签发token(登录接口):视图类已经写好了,配置一下路由就行(urls.py)
# api/urls.py
urlpatterns = [
   # ...
   url('^login/$', ObtainJSONWebToken.as_view()),
]

# Postman请求:/api/login/,提供username和password即可
3、校验token(认证组件):认证类已经写好了,全局配置一下认证组件就行了(settings.py)(全局配置权限组件)
# drf-jwt的配置
import datetime
JWT_AUTH = {
   # 配置过期时间
   'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),
}


# drf配置(把配置放在最下方)
REST_FRAMEWORK = {
   # 自定义三大认证配置类们
   'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework_jwt.authentication.JSONWebTokenAuthentication'],
   # 'DEFAULT_PERMISSION_CLASSES': [],
   # 'DEFAULT_THROTTLE_CLASSES': [],
}
4、设置需要登录才能访问的接口进行测试(views.py)(局部配置认证组件)
from rest_framework.permissions import IsAuthenticated
class UserCenterViewSet(GenericViewSet, mixins.RetrieveModelMixin):
   # 设置必须登录才能访问的权限类
   permission_classes = [IsAuthenticated, ]

   queryset = models.User.objects.filter(is_active=True).all()
   serializer_class = serializers.UserCenterSerializer
5、测试访问登录认证接口(Postman)
"""
1)用 {"username": "你的用户", "password": "你的密码"} 访问 /api/login/ 接口等到 token 字符串

2)在请求头用 Authorization 携带 "jwt 登录得到的token" 访问 /api/user/center/1/ 接口访问个人中心
"""

 

posted @ 2020-02-24 20:08  薛定谔的猫66  阅读(236)  评论(0)    收藏  举报