D j a n g o 后 端 登 录 配 置 Django后端登录配置 Django后端登录配置
1.创建webauth的app
2.在settings中注册authweb
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'apps.drf_demo',
'apps.webauth',
]
3.在webauth中的models中注册自定义用户模型
pip install django-shortuuidfield -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
pip install pyjwt -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
#encoding: utf-8
from django.contrib.auth.models import AbstractBaseUser,PermissionsMixin,BaseUserManager
from shortuuidfield import ShortUUIDField
from django.db import models
class UserManager(BaseUserManager):
def _create_user(self,telephone,username,password,**kwargs):
if not telephone:
raise ValueError('请传入手机号码!')
if not username:
raise ValueError('请传入用户名!')
if not password:
raise ValueError('请传入密码!')
user = self.model(telephone=telephone,username=username,**kwargs)
user.set_password(password)
user.save()
return user
def create_user(self,telephone,username,password,**kwargs):
kwargs['is_superuser'] = False
return self._create_user(telephone,username,password,**kwargs)
def create_superuser(self,telephone,username,password,**kwargs):
kwargs['is_superuser'] = True
kwargs['is_staff'] = True
return self._create_user(telephone,username,password,**kwargs)
class User(AbstractBaseUser,PermissionsMixin):
# 我们不使用默认的自增长的主键
# id:100,101,102,103
# uuid/shortuuid
# Shortuuidfield:pip install django-shortuuidfield
uid = ShortUUIDField(primary_key=True)
telephone = models.CharField(max_length=11,unique=True)
email = models.EmailField(unique=True,null=True)
username = models.CharField(max_length=100)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
data_joined = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'telephone'
# telephone,username,password
REQUIRED_FIELDS = ['username']
EMAIL_FIELD = 'email'
objects = UserManager()
def get_full_name(self):
return self.username
def get_short_name(self):
return self.username
4.在setting中配置AUTH_USER_MODEL
AUTH_USER_MODEL = "webauth.User"
5.映射到数据库
makemigrations
migrate
6.后台登录逻辑实现
先在webauth
重后添加authentications.py
和serializers.py
import jwt
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
from jwt.exceptions import ExpiredSignatureError
MTUser = get_user_model()
import time
def generate_jwt(user):
expire_time = int(time.time() + 60*60*24*7)
return jwt.encode({"userid":user.pk,"exp":expire_time},key=settings.SECRET_KEY)
class JWTAuthentication(BaseAuthentication):
keyword = 'JWT'
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 = "不可用的JWT请求头!"
raise exceptions.AuthenticationFailed(msg)
elif len(auth) > 2:
msg = '不可用的JWT请求头!JWT Token中间不应该有空格!'
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到request对象上
user = MTUser.objects.get(pk=userid)
return user, jwt_token
except:
msg = '用户不存在!'
raise exceptions.AuthenticationFailed(msg)
except ExpiredSignatureError:
msg = "JWT Token已过期!"
raise exceptions.AuthenticationFailed(msg)
from rest_framework.serializers import ModelSerializer
from .models import User
class UserSerializer(ModelSerializer):
class Meta:
model = User
exclude = ['password']
在cms的view.py中写登录逻辑
from rest_framework.views import APIView
from rest_framework.authtoken.serializers import AuthTokenSerializer
from django.utils.timezone import now
from apps.webauth.authentications import generate_jwt
from apps.webauth.serializers import UserSerializer
from rest_framework.response import Response
class LoginView(APIView):
def post(self,request):
serializer = AuthTokenSerializer(data=request.data)
if serializer.is_valid():
user = serializer.validated_data.get('user')
user.last_login = now()
user.save()
token = generate_jwt(user)
user_serializer = UserSerializer(user)
return Response({"token":token,"user":user_serializer.data})
else:
return Response({"message":"用户名或密码错误"})
配置urls
from django.urls import path
from .views import LoginView
app_name = 'cms'
urlpatterns = [
path('login',LoginView.as_view(),name="login")
]
配置主urls
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('cms/', include("apps.cms.urls")),
path('drf_demo/', include('apps.drf_demo.urls')),
]
创建测试数据
createsuperuser --username admin --telephone 18896653148
使用PostMan进行测试
http://127.0.0.1:8000/cms/login