一.上节回顾
1 jwt:重点(跟语言,框架无关)
-json web token
-cookie:客户端浏览器上的键值对,数据不安全
-session:服务端的键值对(内存,数据库,redis,文件),安全,对服务端压力大
-token:三段:头.荷载.签名
-header(公司信息,加密方式...)
-payload(荷载,真正有用的数据部分,用户id,用户名字...)
-signature(签名,把头和荷载部分通过加密算法加密--->得到一个签名)
2 drf-jwt模块
-快速使用:(默认使用的是auth的user表)
-1创建用户
-2在路由中配置path('login/',obtain_jwt_token),
-3在postman中测试,用户名密码输入刚刚创建的用户就可以生成token
-4让一个视图必须登录以后才能访问
-authentication_classes = [JSONWebTokenAuthentication, ]
-permission_classes = [IsAuthenticated,]
-5让一个视图可以登录后访问,也可以不登录访问
-authentication_classes = [JSONWebTokenAuthentication, ]
-6 用postman测试,在请求头中加入
-Authorization jwt adfasdf
-自己写基于jwt的认证类(登录了能访问,不登录就不能访问)
class JwtAuthentication(BaseJSONWebTokenAuthentication):
def authenticate(self, request):
token=request.META.get('HTTP_Authorization'.upper())
try:
payload = jwt_decode_handler(token)
except jwt.ExpiredSignature:
raise AuthenticationFailed('过期了')
except jwt.DecodeError:
raise AuthenticationFailed('解码错误')
except jwt.InvalidTokenError:
raise AuthenticationFailed('不合法的token')
user=self.authenticate_credentials(payload)
return (user, token)
-自定制认证类的使用方式:
-全局使用
-局部使用
3 base64编码(跟语言无关,跟框架无关)
-不同语言的base64可以相互编码解码
-base64内置模块
-图片的二进制,有的时候也会以base64的形式编码
4 drf的视图(两个,5个,9个,视图集)+序列化器+自动生成路由
二.今日内容
1.基于jwt的多方式登录
1 手机号+密码 用户名+密码 邮箱+密码
2 流程分析(post请求):
-路由:自动生成
-视图类:ViewSet(ViewSetMixin,views.APIView)
-序列化类:重写validate方法,在这里面对用户名和密码进行校验
3 代码实现
路由
path('login/', views.LoginViewSet.as_view({
'post':'create'})),
或者:
from rest_framework.routers import SimpleRouter
from app01.views import LoginViewSet
router=SimpleRouter()
router.register('login',LoginViewSet,basename='login')
urlpatterns = [
path('admin/',admin.site.urls),
]
urlpatterns+=router.urls
models.py
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
phone = models.CharField(max_length=32, unique=True)
settings.py
AUTH_USER_MODEL = 'app01.UserInfo'
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'app01.utils.common_exception'
}
视图
from rest_framework.viewsets import ViewSet
from app01.serializer import LoginSerializer
from app01.utils import APIResponse
class LoginViewSet(ViewSet):
def create(self, request, *args, **kwargs):
ser = LoginSerializer(data=request.data)
ser.is_valid(raise_exception=True)
token = ser.context.get('token')
username = ser.context.get('username