用户登录
- 模型类需要继承 AbstractUser
from django.contrib.auth.models import AbstractUser
# 时间
from django.utils import timezone
class User(AbstractUser):
mobile = models.CharField('手机号', max_length=11)
last_login = models.DateTimeField('上次登录时间', default=timezone.now)
def __str__(self):
return self.username
class Meta:
db_table = 'user'
- 还有配置CRUD
# users应用名
AUTH_USER_MODEL = 'users.User
- 需要安装 Djangorestframework-jwt
pip install Djangorestframework-jwt
- 配置路由里面继承 obtain_jwt_token
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
# 用户登录 url: users/login/
path('login/', obtain_jwt_token),
]
- 还需要添加数据密码还得是bash64编码,可以直接在导航栏里输入一下代码
python manage.py shell
>>>from users.mobile import User
>>>User.objects.create_user(username='zhangsan',password='123456',mobile='13111111111')
这样加入的密码是加密的
- 还需要在setting.py里面配置过期时间
from datetime import timedelta
# 配置jwt的过期时间
JWT_AUTH = {
# jwt 过期时间
'JWT_EXPIRATION_DELTA': timedelta(bays=2),
}
- 可以直接在ApiPost里面测试,此时他还返回一个token
- 我们性让他返回编号和姓名的话,在应用里面创建一个utils.py文件写入代码
def jwt_response_payload_handler(token, user, request, *args, **kwargs):
return {
'uid': user.id,
'username': user.username,
'token': token
}
- 配置项目
# 配置jwt的时间
JWT_AUTH = {
# jwt 过期时间
'JWT_EXPIRATION_DELTA': timedelta(days=2),
# 配置自定义函数
'JWT_RESPONSE_PAYLOAD_HANDLER': 'users.utils.jwt_response_payload_handler',
}
这样就可以返回用户的名字和编号
- 还可以以管理员身份认证,还是在utils.py文件中写入代码
from .models import User
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.hashers import check_password
# 定义自己的认证类
class MyAuthentication(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
# 根据需求查询用户对象
user = User.objects.filter(username=username, is_active=True, is_staff=True).first()
# 判断用户是否存在, 密码是否正确
if user and check_password(password, user.password):
return user
else:
return None
- 还需要配置
# 配置自定义的认真类
AUTHENTICATION_BACKENDS = [
'users.utils.MyAuthentication',
]
创建短信验证码
- 打开容联云注册一个用户
容联云地址:https://www.yuntongxun.com/
- 获取三条数据保存好
- 选着自己的手机号
- 然后在utils.py里面封装请求方法
from ronglian_sms_sdk import SmsSDK
import json
accId = '8aaf07088185853e01818a78d71c0195' # 主账户ID
accToken = '982f2e6dd6a5*********4bc22ac7206' # 账户授权令牌
appId = '8aaf07088185853e01818a78d80e019c' # 默认
# 定义发送短信的函数
def send_message(sms_code, mobile, expire=5):
"""
:param sms_code: 要发送的验证码
:param mobile: 发送的手机号
:param expire: 过期时间
:return:
"""
# 实例化sdk对象
sdk = SmsSDK(accId=accId, accToken=accToken, appId=appId)
# 准备数据
tid = '1'
datas = ("%s" % sms_code, "%s" % expire)
# 发送短信
res = sdk.sendMessage(tid=tid, mobile=mobile, datas=datas)
# 解析json字符串
data = json.loads(res)
print('容联云响应的数据:', data)
if data.get('statusCode') == '000000':
return True
return False
- 在视图层里面写入方法
# 短信验证码视图
class SmsCodeAPIView(APIView):
# 发送短信验证码
def get(self, request):
# 获取前端的手机号
mobile = request.query_params.get('mobile')
# 生成短信验证码
sms_code = random.randint(1000, 9999)
# 发送短信
result = send_message(sms_code, mobile, expire=5)
if result:
# 存储短信到redis中
redis_conn = redis.Redis(host='127.0.0.1', port=6379)
key = 'sms_%s'%mobile
redis_conn.set(key, sms_code, ex=300)
return Response({'code': 200, 'msg': '发送短信验证码成功'})
else:
return Response({'code': 400, 'msg': '发送失败'})
- 配置路由
from django.urls import path
from users import views
urlpatterns = [
path('sms_code/', views.views.SmsCodeAPIView.as_view()),
]
在ApiPost中测试一下