一、认证
1.Browsable API页面认证与JWT认证比较
1.Browsable API页面认证
- 指定permission_classes
- 添加rest_framework.urls路由
2.Json Web Token认证
- 最常用的认证方式
- Session认证
- Token认证
- Session认证
- 保存在服务端,增加服务器开销
- 分布式架构中,难以维持Session会话同步
- CSRF攻击风险
- Token认证
- 保存在客户端
- 跨语言、跨平台
- 拓展性强
- 鉴权性能高
- JWT
- 由三部分组成
- header、playload、signature
- 由三部分组成
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhemF6aWUiLCJhdWQiOiJ1c2VycyIsImlhdCI6MTU5NTY3NTA1NiwiZXhwIjoxNTk2Mjc5ODU2LCJ1c2VyX2lkIjozMDI3NTQxfQ.vJPcwpw4_WBLGBkXO3SUPbyfgDzk4S3FwWzJrCtvhwA
-
- header
- 声明类型
- 声明加密算法,默认为HS256
- base64加密,可以解密
- playload
- 存放过期时间、签发用户等
- 可以添加用户的非敏感信息
- base64加密,可以解密
- signature
- 有三部分组成
- 使用base64加密之后的header+.+使用base64加密之后的playload+.+使用HS256算法加密,同时secret加盐处理
- header
2.Browsable API页面认证
1.源码
'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication' ]
2.说明
BasicAuthentication:基本的用户密码认证
SessionAuthentication:session会话认证
SessionAuthentication和BasicAuthentication二者缺一不可,相辅相成,我们也可以在此基础上增加别的认证,如:token认证、微信/QQ第三方认证、LADP认证
在authentication.py模块中,除了上面这两种,还有其它的认证方式可供选择:
3.指定视图下认证
authenticcation_classes = [] # 列表中添加对应的认证方式
一般不需要指定视图下进行认证,往往一个项目下只会使用一种认证方式
4.创建超级管理员
命令行
python manage.py createsuperuser --username USERNAME --email EMAIL
5.添加路由
这里提供的是一种前后端不分离的登录,后面会舍弃掉
在全局下的urls.py中添加如下代码
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('rest_framework.urls'))
]
我们可以去看看rest_framework下的urls.py
配置了之后就已经提供了登录和登出的接口
6.登录
2.JWT认证
1.jwt实现原理
1.安装jwt
pip install -i https://pypi.douban.com/simple pyjwt
2.引入jwt
import jwt
3.指定header和playload
header一般不需要指定,使用默认值即可
指定后端需要存放的一些非敏感信息
playload = { 'username': '小公瑾', 'age': 18 }
3.服务端创建token令牌
token = jwt.encode(playload, key='user') # key由服务器来规定
4.服务端对前端用户传递的token进行解密
res = jwt.decode(token, key='user')
2.drf的token认证实现方法
1.安装djangorestframework-jwt
pip install -i https://pypi.douban.com/simple djangorestframework-jwt
2.全局配置指定JWT Token认证
一定要注意列表是有优先级的,需要把该认证放到第一个位置
REST_FRAMEWORK = { # 认证方式 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication' ] }
3.根路由配置user模块
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('user/', include('user.urls')) ]
4.user子模块下添加路由
from django.urls import path from rest_framework_jwt.views import obtain_jwt_token urlpatterns = [ path('login/', obtain_jwt_token) ]
5.验证结果
6.重写jwt_response
1).重写jwt_response_payload_handler
def jwt_response_payload_handler(token, user=None, request=None): return { 'user_id': user.id, 'username': user.username, 'token': token }
2).注册重写的方法
将rest_framework_jwt中的全局配置进行覆盖,源码配置如下:
3).在全局配置中重写配置
JWT_AUTH = { 'JWT_RESPONSE_PAYLOAD_HANDLER': 'utils.jwt_handler.jwt_response_payload_handler' }
7.验证结果
8.其它配置和说明
1).其它接口认证
- 前端用户访问一些需要认证之后的接口,那么默认需要在请求头中携带参数
- 请求key默认为Authorization,值为前缀+空格+token值,如:
JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhemF6aWUiLCJhdWQiOiJ1c2VycyIsImlhdCI6MTU5NTY3NTA1NiwiZXhwIjoxNTk2Mjc5ODU2LCJ1c2VyX2lkIjozMDI3NTQxfQ.vJPcwpw4_WBLGBkXO3SUPbyfgDzk4S3FwWzJrCtvhwA
2).修改token过期时间
覆盖rest_framework_jwt配置
import datetime JWT_AUTH = { 'JWT_RESPONSE_PAYLOAD_HANDLER': # token过期时间默认为300秒,这里可以自定义 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1), }
二、授权
1.源码
'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.AllowAny', ]
2.说明
源码中只提供了AllowAny的授权,它表示不限制任何权限,一般情况下,这种授权不会满足要求,我们可以看看permissions.py模块下提供的其它授权
AllowAny:任意权限
IsAuthenticated:允许登录后拥有权限
IsAdminUser:管理员权限
IsAuthenticatedOrReadOnly:未登录下只允许浏览
3.指定视图下权限
permission_classes = [permissions.AllowAny]
permissions需要引入
from rest_framework import permissions