1 再也不使用Session认证机制,而使用Json Web Token(本质就是token)认证机制,用户登陆认证 2 用户只要登陆了,返回用户一个token串(随机字符串),每次用户发请求,须要携带这个串过来,验证经过,咱们认为用户登陆了 3 JWT的构成(字符串) -三部分(每一部分中间经过.分割):header payload signature -header:声明类型,这里是jwt,声明加密算法,头里加入公司信息...,用base64转码 { 'typ': 'JWT', 'alg': 'HS256' #用md5也行 } -payload:荷载(有用),当前用户的信息(用户名,id,这个token的过时时间,手机号),用base64转码 { "sub": "1234567898", "name": "egon", "admin": true, "userid":1, 'mobile':123444444 } -signature:签名 -把前面两部分的内容经过加密算法+密钥加密后获得的一个字符串 -jwt总的构成样子: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ 4 JWT认证原理 -用户携带用户名,密码登陆个人系统,校验经过,生成一个token(三部分),返回给用户---》登陆功能完成 -访问须要登陆的接口(用户中心),必须携带token过来,后端拿到token后,把header和payload截出来,再经过同样的加密方式和密码获得一个signature,
和该token的signature比较,若是同样,表示是正常的token,就能够继续日后访问
安装前端
1 drf中使用jwt,借助第三方https://github.com/jpadilla/django-rest-framework-jwt
2 安装 pip3 install djangorestframework-jwt
快速使用git
3 快速使用(默认使用auth的user表) (1) 在默认auth的user表中建立一个用户 (2) 在路由中配置 from rest_framework_jwt.views import obtain_jwt_token path('login/', obtain_jwt_token), (3) 用postman向这个地址发送post请求,携带用户名,密码,登录成功就会返回token (4)obtain_jwt_token本质也是一个视图类,继承了APIView -经过前端传入的用户名密码,校验用户,若是校验经过,生成token,返回 -若是校验失败,返回错误信息 访问地址:http://127.0.0.1:8000/homework/login/
用户登陆之后才能访问某个接口github
4 用户登陆之后才能访问某个接口 -jwt模块内置了认证类,拿过来局部配置就能够 -class OrderView(APIView): # 只配它不行,无论是否登陆,都能范围,须要搭配一个内置权限类 authentication_classes = [JSONWebTokenAuthentication, ] permission_classes = [IsAuthenticated,] def get(self, request): print(request.user.username) return Response('订单的数据') 访问地址: http://127.0.0.1:8000/homework/order/ 注意:访问的时候须要在header内携带jwt
用户未登陆,能够访问算法
5 用户未登陆,能够访问 -class OrderView(APIView): # 只配它不行,无论是否登陆,都能范围,须要搭配一个内置权限类 authentication_classes = [JSONWebTokenAuthentication, ] def get(self, request): print(request.user.username) return Response('订单的数据') 访问地址: http://127.0.0.1:8000/homework/order/
注意事项django
6 若是用户携带了token,而且配置了JSONWebTokenAuthentication,从request.user就能拿到当前登陆用户,若是没有携带,当前登陆用户就是匿名用户 7 前端要发送请求,携带jwt,格式必须以下 -把token放到请求头header中,key为:Authorization -value必须为:jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo1LCJ1c2VybmFtZSI6ImVnb24xIiwiZXhwIjoxNjA1MjQxMDQzLCJlbWFpbCI6IiJ9.7Y3PQM0imuSBc8CUe_h-Oj-2stdyzXb_U-TEw-F82WE
1 控制登陆接口返回的数据格式以下 { code:100 msg:登陆成功 token:asdfasfd username:egon } 2 写一个函数utils.py from homework.serializer import UserReadOnlyModelSerializer def jwt_response_payload_handler(token, user=None, request=None): return {'code': 100, 'msg': '登陆成功', 'token': token, 'user': UserReadOnlyModelSerializer(instance=user).data } 3 在setting.py中配置 import datetime JWT_AUTH = { 'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.utils.jwt_response_payload_handler', }
1 本身实现基于jwt的认证类,经过认证,才能继续访问,通不过认证就返回错误
2 本身写个类auth.py class JwtAuthentication(BaseJSONWebTokenAuthentication): def authenticate(self, request): # 认证逻辑() # token信息能够放在请求头中,请求地址中 # key值能够随意叫 # token=request.GET.get('token') token=request.META.get('HTTP_Authorization'.upper()) # 校验token是否合法 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 在视图类中配置 authentication_classes = [JwtAuthentication, ] # 视图views.py全代码: from app01.auth import JwtAuthentication class OrderView(APIView): # 登陆之后才能访问 authentication_classes = [JwtAuthentication, ] def get(self, request): print(request.user.username) return Response('订单的数据')