认证:
def的request对象 上便有两个属性,一个是request.user,一个是request.auth,前者就是django中User对象,后者根据不同认证机制有不同的对象
rest_framework.authentication.BasicAuthentication
基本的授权,每次都要在Header中把用户名和密码传给服务器,因此不是很安全,不能在生产环境中使用
rest_framework.authentication.SessionAuthentication
基于 django的session机制实现,如果前端部分是网页,那么用他是可以的,如果前端是ios或安卓,用它就不太方便
rest_framework.authentication.TokenAuthentication
基于token的认证机制,只要登陆完成便会返回一个token,以后请求一些需要登陆的api,就通过传递这个token就可以了,并且这个token是存储服务器的数据库中的,但是这种token的方式有一个缺点,就是他没有自动过期机制
JSON Web Token 认证机制:
json web token 简称 jwt 推荐使用 jwt 是在成功后,把用户的相关信息(比如用户id)以及过期时间进行加密,然后生成一个token返回给客户端,客户端拿到后可以存储起来,以后每次请求的时候都携带这个token,服务器在接收需要登陆api请求,这个token进行解密,然后获取过期时间和用户信息,如果过期了或者用户信息不对,那么都是认证失败
# -*- coding: utf-8 -*-
from rest_framework import viewsets
from meituan.models import Merchant
from .serializers import MerchantSerializer
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated
class MerchantViewSet(viewsets.ModelViewSet):
queryset = Merchant.objects.all()
serializer_class = MerchantSerializer
# 用来验证用户是否已经成功登陆
authentication_classes = [BasicAuthentication]
# 权限 经过授权才能访问
permission_classes = [IsAuthenticated]
没有授权
Django 创建超级用户
手动实现JWT认证
pip install pyjwt
import jwt
import time
from django.conf import settings
def generate_jwt(user):
# 设置过期时间
timestamp = int(time.time()) + 60*60*24*7
# 因为jwt.encode 返回的是bytes 数据类型,因此需要decode解码成str类型
return jwt.encode({"userid":user.pk,"exp":timestamp},settings.SECRET_KEY).encode('utf-8')
from .authentications import generate_jwt
from django.contrib.auth import get_user_model
from rest_framework.response import Response
from rest_framework.decorators import api_view
User = get_user_model()
# 模拟登陆
@api_view(['GET'])
def token_view(request):
token = generate_jwt(User.objects.first())
return Response({"token":token})
jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyaWQiOjEsImV4cCI6MTY2Mzc2ODAwMS4zNzgwODQyfQ._ktzqs2_FYSGmpZ4FZjdzTMr4BjD_IxLVKpPtyf03jQ
# -*- coding: utf-8 -*-
import jwt
import time
from django.conf import settings
from rest_framework.authentication import BaseAuthentication,get_authorization_header
from rest_framework import exceptions
from django.contrib.auth import get_user_model
User = get_user_model()
def generate_jwt(user):
# 设置过期时间
timestamp = int(time.time()) + 60*60*24*7
# 因为jwt.encode 返回的是bytes 数据类型,因此需要decode解码成str类型
return jwt.encode({"userid":user.pk,"exp":timestamp},settings.SECRET_KEY).decode('utf-8')
class JWTAuthentication(BaseAuthentication):
"""
Authorization: Token 401f7ac837da42b97f613d789819ff93537bee6a
"""
keyword = 'jwt'
model = None
def authenticate(self, request):
auth = get_authorization_header(request).split()
if not auth or auth[0].lower() != self.keyword.lower().encode():
return None
if len(auth) == 1:
msg = 'Authorization 不可用!'
raise exceptions.AuthenticationFailed(msg)
elif len(auth) > 2:
msg = 'Authorization 不可用! 应该提供一个空格!'
raise exceptions.AuthenticationFailed(msg)
try:
jwt_token = auth[1]
jwt_info = jwt.decode(jwt_token,settings.SECRET_KEY)
userid = jwt_info.get('userid')
try:
user = User.objects.get(pk=userid)
return (user,jwt_token)
except:
msg = "用户不存在!"
raise exceptions.AuthenticationFailed(msg)
except UnicodeError:
msg = "token 已经过期了!"
raise exceptions.AuthenticationFailed(msg)
# -*- coding: utf-8 -*-
from rest_framework import viewsets
from meituan.models import Merchant
from .serializers import MerchantSerializer
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated,AllowAny,IsAdminUser
from .authentications import generate_jwt,JWTAuthentication
from django.contrib.auth import get_user_model
from rest_framework.response import Response
from rest_framework.decorators import api_view
User = get_user_model()
class MerchantViewSet(viewsets.ModelViewSet):
queryset = Merchant.objects.all()
serializer_class = MerchantSerializer
# 用来验证用户是否已经成功登陆
authentication_classes = [JWTAuthentication,BasicAuthentication]
# 权限 经过授权才能访问
permission_classes = [IsAuthenticated,IsAdminUser]
# AUTHORIZATION
# basic username:password
# 模拟登陆
@api_view(['GET'])
def token_view(request):
token = generate_jwt(User.objects.first())
return Response({"token":token})
jwt decode error is It is required that you pass in a value for the “algorithms“ argument when calli