用django框架开发一个B2C购物网站用户注册知识点总结2
一:用户部分:
用户注册:
用户注册序列化器:
import re from django_redis import get_redis_connection
from rest_framework import serializers from users.models import User class CreateUserSerializer(serializers.ModelSerializer):
"""创建用户序列化器类"""
password2 = serializers.CharField(label='重复密码', write_only=True)
sms_code = serializers.CharField(label='短信验证码', write_only=True)
allow = serializers.CharField(label='是否同意协议', write_only=True)
token = serializers.CharField(label='JWT Token', read_only=True) class Meta:
model = User
fields = ('id', 'username', 'password', 'mobile', 'password2', 'sms_code', 'allow', 'token') extra_kwargs = {
'username': {
'min_length': 5,
'max_length': 20,
'error_messages': {
'min_length': '仅允许5-20个字符的用户名',
'max_length': '仅允许5-20个字符的用户名',
}
},
'password': {
'write_only': True,
'min_length': 8,
'max_length': 20,
'error_messages': {
'min_length': '仅允许8-20个字符的密码',
'max_length': '仅允许8-20个字符的密码',
}
}
} # (参数完整性,手机号格式,手机号是否已注册,是否同意协议,两次密码是否一致,短信验证码是否正确)
def validate_username(self, value):
"""用户名不能是纯数字"""
if re.match(r'^\d+$', value):
raise serializers.ValidationError('用户名不能都是数字') return value def validate_mobile(self, value):
"""手机号格式,手机号是否已注册"""
# 手机号格式
if not re.match(r'^1[3-9]\d{9}$', value):
raise serializers.ValidationError('手机号格式不正确') # 手机号是否已注册
count = User.objects.filter(mobile=value).count()
if count > 0:
raise serializers.ValidationError('手机号已存在') return value def validate_allow(self, value):
"""是否同意协议"""
if value != 'true':
raise serializers.ValidationError('请同意协议')
return value def validate(self, attrs):
"""两次密码是否一致,短信验证码是否正确"""
# 两次密码是否一致
password = attrs['password']
password2 = attrs['password2'] if password != password2:
raise serializers.ValidationError('两次密码不一致') # 短信验证码是否正确
# 获取真实的短信验证码内容
mobile = attrs['mobile']
redis_conn = get_redis_connection('verify_codes')
real_sms_code = redis_conn.get('sms_%s' % mobile) # bytes if not real_sms_code:
raise serializers.ValidationError('短信验证码已过期') # 对比
sms_code = attrs['sms_code'] # str
real_sms_code = real_sms_code.decode() # str
if sms_code != real_sms_code:
raise serializers.ValidationError('短信验证码错误') return attrs def create(self, validated_data):
"""保存注册用户信息"""
# 清除无用的数据
del validated_data['password2']
del validated_data['sms_code']
del validated_data['allow'] # # 调用父类create方法
# user = super().create(validated_data)
#
# # 对密码进行加密
# password = validated_data['password']
# user.set_password(password)
# user.save() # 调用create_user方法
user = User.objects.create_user(**validated_data) # 注册成功就让用户处于登录状态
# 由服务器签发一个jwt token,保存用户身份信息
from rest_framework_jwt.settings import api_settings jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER # 生成载荷信息(payload)
payload = jwt_payload_handler(user)
# 生成jwt token
token = jwt_encode_handler(payload) # 给user对象增加一个属性token,保存jwt token信息
user.token = token # 返回user
return user
对应视图函数:
from django.shortcuts import render
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView, CreateAPIView from users.models import User
from users.serializers import CreateUserSerializer
# Create your views here. # POST /users/
# class UserView(GenericAPIView):
class UserView(CreateAPIView):
serializer_class = CreateUserSerializer # def post(self, request):
# """
# 注册用户信息的保存:
# 1. 获取参数并进行校验(参数完整性,两次密码是否一致,手机号格式,手机号是否已注册,短信验证码是否正确,是否同意协议)
# 2. 保存注册用户信息
# 3. 返回应答,注册成功
# """
# # 1. 获取参数并进行校验(参数完整性,两次密码是否一致,手机号格式,手机号是否已注册,短信验证码是否正确,是否同意协议)
# serializer = self.get_serializer(data=request.data)
# serializer.is_valid(raise_exception=True)
#
# # 2. 保存注册用户信息(create)
# serializer.save()
#
# # 3. 返回应答,注册成功
# return Response(serializer.data, status=status.HTTP_201_CREATED) # url(r'^usernames/(?P<username>\w{5,20})/count/$', views.UsernameCountView.as_view()),
class UsernameCountView(APIView):
"""
用户名数量
"""
def get(self, request, username):
"""
获取指定用户名数量
"""
count = User.objects.filter(username=username).count() data = {
'username': username,
'count': count
} return Response(data) # url(r'^mobiles/(?P<mobile>1[3-9]\d{9})/count/$', views.MobileCountView.as_view()),
class MobileCountView(APIView):
"""
手机号数量
"""
def get(self, request, mobile):
"""
获取指定手机号数量
"""
count = User.objects.filter(mobile=mobile).count() data = {
'mobile': mobile,
'count': count
} return Response(data)
用到的知识点:
##### 2. JWT token 1)session认证 ```python
1. 接收用户名和密码
2. 判断用户名和密码是否正确
3. 保存用户的登录状态(session)
session['user_id'] = 1
session['username'] = 'smart'
session['mobile'] = ''
4. 返回应答,登录成功
``` session认证的一些问题: > 1. session存储在服务器端,如果登录的用户过多,服务器开销比较大。
> 2. session依赖于cookie,session的标识存在cookie中,可能会有CSRF(跨站请求伪造)。 2)jwt 认证机制(替代session认证) ```
1. 接收用户名和密码
2. 判断用户名和密码是否正确
3. 生成(签发)一个jwt token(token中保存用户的身份信息) 公安局(服务器)=>签发身份证(jwt token)
4. 返回应答,将jwt token信息返回给客户端。
``` 如果之后需要进行身份认证,客户端需要将jwt token发送给服务器,由服务器验证jwt token的有效性。 3)jwt 的数据格式 ```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ik
pvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFO
``` a)headers头部 ```
{
"token类型声明",
"加密算法"
}
``` base64加密(很容易被解密) b)payload(载荷):用来保存有效信息 ```
{
"user_id": 1,
"username": "smart",
"mobile": "",
"exp": "有效时间"
}
``` base64加密 c)signature(签名):防止jwt token被伪造 将headers和payload进行拼接,用.隔开,使用一个密钥(secret key)进行加密,加密之后的内容就是签名。 jwt token是由服务器生成,密钥保存在服务器端。 ##### 3. jwt 扩展签发jwt token
from rest_framework_jwt.settings import api_settings jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
用django框架开发一个B2C购物网站用户注册知识点总结2的更多相关文章
- 用django框架开发一个B2C购物网站的基本流程和用到的知识点总结1
开发流程 开发模式采用前后端分离模式,作为后端开发人员我们只关注后端业务逻辑开发: 省略项目框架搭建文件的配置部分.... 一:用户部分 在项目开发中我们要用到用户模型类User,Django认证系统 ...
- 基于django快速开发一个网站(一)
基于django快速开发一个网站(一) * 创建虚拟环境.基于虚拟环境创建django==2.0.0和图片加载库和mysql数据库驱动 1. 创建目录并创建虚拟环境 ╰$ mkdir Cornuco ...
- 基于Spring+Spring MVC+Mybatis的B2C购物网站
代码地址如下:http://www.demodashi.com/demo/12935.html 准备工作 当前项目运行的系统环境是MacOS,已经测试可以正常运行,并且之前开发的时候也在Windows ...
- YII框架开发一个项目的通用目录结构
YII框架开发一个项目的通用目录结构: 3 testdrive/ 4 index.php Web 应用入口脚本文件 5 assets/ 包含公开的资源文件 6 css/ 包含 CSS 文件 7 ima ...
- 使用Phalcon框架开发一个简易的博客系统
使用Phalcon PHP框架开发一个简易的博客系统(类似于CMS) 最近在做Phalcon(Phalcon在英文中指的是鸟类中飞得最快的那一个物种,由于是高性能框架,借用了这个词)相关的项目,由于刚 ...
- php怎么做网站?如何用PHP开发一个完整的网站?
1.PHPer应具备的知识 (1)PHP知识: 熟练掌握基础函数,PHP语句(条件.循环),数组(排序.读取),函数(内部 构造),运算(数学 逻辑),面向对象(继承 接口 封装 多态静态属性)等. ...
- jQuery框架开发一个最简单的幻灯效果
在线演示 在这个课程中,我们将介绍如何使用jQuery来开发一个最简单的图片幻灯效果. 立刻观看互动课程:jQuery框架开发一个最简单的幻灯效果 阅读原文:jQuery框架开发一个最简单的幻灯效果
- 第六模块:WEB框架开发 第1章·Django框架开发88~128
88-Ajax简介 89-Ajax的简单实现 90-基于Ajax的传递数据 91-基于Ajax的登录验证 92-基于Form表单的文件上传 93-请求头之contentType 94-Ajax传递js ...
- 第六模块:WEB框架开发 第1章·Django框架开发1~50
01-Django基础介绍 02-Web应用程序1 03-Web应用程序2 04-http请求协议1 05-http请求协议2 06-http协议之响应协议 07-wsgire模块1 08-wsgir ...
随机推荐
- 用firefox获取html页面元素的Xpath
Xpath在分析网页尤其是采集固定格式数据时,非常有用,且比正则表达式和首尾截取式更加简便.准确! 工具/原料 FireFox FireBug XpathChecker UserAgentSwit ...
- PHP5.3、PHP5.4、PHP5.5、PHP5.6的新特性
1. PHP5.3中的新特性 1.1 支持命名空间(namespace) 毫无疑问,命名空间是PHP5.3所带来的最重要的新特性. 在PHP5.3中,可以用命名空间防止代码的冲突,命名空间的分隔符为 ...
- Matlab 之 FFT的理解和应用
网上看了一些大牛的关于FFT的见解,加上自己的一点儿理解,针对以下这几个问题来加深对FFT的理解. 不知道大家有没有类似以下几点的困惑: 问题的提出 对于1秒钟输出的连续信号,使用采样率Fs不同,就会 ...
- POJ2503:Babelfish
浅谈\(Trie\):https://www.cnblogs.com/AKMer/p/10444829.html 题目传送门:http://poj.org/problem?id=2503 \(Trie ...
- Maven使用中的常见问题整理
1.更新eclipse的classpath加入新依赖 1.在dependencyManagement里面加入包括版本在内的依赖信息,如: <dependency> <groupId ...
- onclick监听
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- CArray,CList,CMap如何实例化
1.定义一个CMap,向这个CMap中增加数据项(键-值对).CMap<CString, LPCTSTR, CString, LPCTSTR>m_ItemMap;CString strKe ...
- spring面试资料
* Spring的优点有什么? 1. Spring是分层的架构,你可以选择使用你需要的层而不用管不需要的部分 2. Spring是POJO编程,POJO编程使得可持续构建和可测试能力提高 ...
- java代码-----实现4个人打牌游戏的相关代码。线程
总结:发送线程Sender().和接收线程Receiver() 虽然,这里的Sender()发送线程和Receiver()都有相同的睡眠时间,但是由于线程调度的不确定性,是的发送线程Sender每次发 ...
- s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加由用户控制。
package com.hanqi; import java.util.*; public class yonghukongzhi { public static void main(String[] ...