尝试使用simplejwt
pip install djangorestframework-simplejwt
尝试在 middleware.py 中执行此操作
from django.contrib.auth.middleware import get_user
from django.utils.functional import SimpleLazyObject
from rest_framework_simplejwt.authentication import JWTTokenUserAuthentication
from rest_framework.exceptions import AuthenticationFailed
import jwt
from django.conf import settings
from django.contrib.auth.models import User, AnonymousUser
class JWTAuthenticationMiddleware(object):
# print("a")
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
request.user = SimpleLazyObject(lambda:self.__class__.get_jwt_user(request))
# print(request.user)
return self.get_response(request)
# def process_request(self, request):
# request.user = SimpleLazyObject(lambda: self.__class__.get_jwt_user(request))
@staticmethod
def get_jwt_user(request):
# print(request.user)
# user = get_user(request)
# user = AnonymousUser()
try:
access_token = request.COOKIES['jwtt']
except KeyError:
raise AuthenticationFailed(
"Key missing try to login" \
" again (you logged out by timeout)"
)
if not access_token:
raise AuthenticationFailed(
'unaunticated access token missing'
)
# user = AnonymousUser()
try:
payload = jwt.decode(
access_token,
settings.SECRET_KEY,
algorithms=['HS256']
)
user = User.objects.get(id=payload['user_id'])
except jwt.ExpiredSignatureError:
# raise AuthenticationFailed(
# 'unautneticated'
# )
user = AnonymousUser()
我的views.py
from rest_framework.exceptions import AuthenticationFailed
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status, generics
from rest_framework.permissions import AllowAny
from django.conf import settings
import jwt
from django.contrib.auth.models import User
from .serializers import (
UserListSerializer, UserRegistrationSerializer,
UserLoginSerializer, MyTokenObtainPairSerializer
)
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework.decorators import api_view
from django.http import JsonResponse, response
from termcolor import colored
from rest_framework.settings import api_settings
from rest_framework import permissions
class MyTokenObtainPairView(TokenObtainPairView):
serializer_class = MyTokenObtainPairSerializer
@api_view(['GET'])
def getRoutes(request):
routes = [
'/api/token',
'/api/token/refresh'
]
return JsonResponse(routes)
class AuthUserRegistrationView(APIView):
serializer_class = UserRegistrationSerializer
permission_classes = (AllowAny,)
def post(self, request):
serializer = self.serializer_class(data=request.data)
valid = serializer.is_valid(raise_exception=True)
print(colored(request.user, 'red'))
if valid:
serializer.save()
data = serializer.data
try:
data.pop('password')
except KeyError:
pass
status_code = status.HTTP_201_CREATED
response = {
'success': True,
'statusCode': status_code,
'message': 'User successfully registered!',
'user': data
}
return Response(response, status=status_code)
class AuthUserLoginView(APIView):
serializer_class = UserLoginSerializer
permission_classes = (AllowAny,)
def post(self, request):
serializer = self.serializer_class(data=request.data)
valid = serializer.is_valid(raise_exception=True)
if valid:
status_code = status.HTTP_200_OK
response = {
'success': True,
'statusCode': status_code,
'message': 'login sucessfully',
'access': serializer.data['access'],
'refresh': serializer.data['refresh'],
'authenticatedUser': {
'username': serializer.data['username'],
}
}
r = Response(response)
r.set_cookie(key='jwtt', value=serializer.data['access'])
return r
class UserListView(generics.ListAPIView):
serializer_class = UserListSerializer
permission_classes = (
permissions.IsAuthenticatedOrReadOnly,
)
def get(self, request):
print(colored(request.user, 'red'))
try:
access_token = request.COOKIES['jwtt']
except KeyError:
raise AuthenticationFailed(
"Key missing try to login " \
"again(you have been loged out)"
)
if not access_token:
raise AuthenticationFailed(
'unaunticated access token missing'
)
try:
# print(colored('start', 'blue'))
payload = jwt.decode(access_token,
settings.SECRET_KEY,
algorithms=['HS256']
)
# print(colored(access_token, 'red'))
except jwt.ExpiredSignatureError:
raise AuthenticationFailed(
'unauthenticated'
)
user = User.objects.get(id=payload['user_id'])
if user:
users = User.objects.all()
serializer = self.serializer_class(users, many=True)
status_code = status.HTTP_200_OK
response = {
'success': True,
'status_code': status_code,
'message': 'Successfully fetched users',
'users': serializer.data
}
return Response(
response, status=status_code
)
else:
status_code = status.HTTP_401_UNAUTHORIZED
response = {
'success': False,
'status_code': status_code,
'message': 'UserDoes not authorized'
}
return Response(response, status=status_code)
class LogoutView(APIView):
def get(self, request):
response = Response()
response.delete_cookie('jwtt')
response.data = {
'message': 'logout successfully'
}
return response
我的serializers.py
from tokenize import Token
from django.contrib.auth import authenticate
from django.contrib.auth.models import update_last_login
from django.contrib.auth.models import User
from django.http import request
from rest_framework import serializers
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.tokens import RefreshToken
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
token = super().get_token(user)
token['username'] = user.username
return token
class UserRegistrationSerializer(serializers.ModelSerializer):
password = serializers.CharField(
max_length=128, write_only=True,
style = {
'input_type': 'password',
'placeholder': 'Password'
}, required=True
)
class Meta:
model = User
fields = (
'username',
'email',
'password'
)
def create(self, validated_data):
auth_user = User.objects.create_user(
**validated_data
)
return auth_user
class UserLoginSerializer(serializers.Serializer):
username = serializers.CharField(
max_length=128
)
password = serializers.CharField(
max_length=128, write_only=True
)
access = serializers.CharField(read_only=True)
refresh = serializers.CharField(read_only=True)
def create(self, validated_data):
pass
def update(self, instance, validated_data):
pass
def validate(self, data):
username = data['username']
password = data['password']
user = authenticate(username=username, password=password)
if user is None:
raise serializers.ValidationError(
'invalid login credential'
)
try:
refresh = RefreshToken.for_user(user)
refresh_token = str(refresh)
access_token = str(refresh.access_token)
update_last_login(
None, user
)
validation = {
'access': access_token,
'refresh': refresh_token,
'username': user.username,
}
return validation
except User.DoesNotExist:
raise serializers.ValidationError('User does not exesists')
class UserListSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = (
'username', 'email',
)
note every things are in account directory or you can say account app