【Django开发】前后端分离美多商城项目第6篇:用户部分,1. 业务说明【附代码文档】

美多商城项目4.0文档完整教程(附代码资料)主要内容讲述:美多商城,项目准备1.B2B--企业对企业,2.C2C--个人对个人,3.B2C--企业对个人,4.C2B--个人对企业,5.O2O--线上到线下,6.F2C--工厂到个人。项目准备,配置1. 修改settings/dev.py 文件中的路径信息,2. INSTALLED_APPS,3. 数据库,4. Redis,5. 本地化语言与时区,6. 日志。用户部分,图片验证码。用户部分,使用Celery完成发送短信1. 判断用户名是否存在,2. 判断手机号是否存在:。用户部分,JWT起源,基于token的鉴权机制,JWT长什么样?,JWT的构成,总结,安装配置。用户部分,登录创建模型类,urllib使用说明。登录,登录回调处理创建模型类,urllib使用说明。登录,绑定用户身份接口创建模型类,urllib使用说明。邮件与验证,保存邮箱并发送验证邮件。收货地址,省市区地址查询。收货地址,使用缓存。商品部分,数据库表设计表结构,数据库模型类,1. 什么是FastDFS,2. 文件上传流程,3. 简易FastDFS构建。Docker使用,Docker简介1. 虚拟化,2. 什么是Docer,3. Docker组件,4 使用Docker做什么。Docker使用,安装与操作1. 在Ubuntu中安装Docker,2. 启动与停止,3. Docker镜像操作,4. Docker 容器操作,5. 将容器保存为镜像,6. 镜像备份与迁移。商品部分,FastDFS客户端与自定义文件存储系统1. FastDFS的Python客户端,2. 自定义Django文件存储系统,3. 在Django配置中设置自定义文件存储类,4. 添加image域名。商品部分,页面静态化。商品部分,商品详情页。商品部分,用户浏览历史记录1. 保存,2. 查看,获取商品列表数据。商品部分,商品搜索。购物车部分,购物车数据存储设计1. Redis保存已登录用户,2. Cookie保存未登录用户。购物车部分,查询购物车数据。购物车部分,登录合并购物车。订单部分,保存订单。支付,接入。Xadmin,用户权限控制1. 安装,2. 使用,1. 主从同步的定义,2. 主从同步的机制,3. 配置主从同步的基本步骤,4. 详细配置主从同步的方法。

全套笔记资料代码移步: 前往gitee仓库查看

感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~


全套教程部分目录:


部分文件图片:

用户部分

登录

1. 业务说明

验证用户名和密码,验证成功后,为用户签发JWT,前端将签发的JWT保存下来。

2. 后端接口设计

请求方式: POST /authorizations/

请求参数: JSON 或 表单

参数名类型是否必须说明
usernamestr用户名
passwordstr密码

返回数据: JSON

{"username": "python","user_id": 1,"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo5LCJ1c2VybmFtZSI6InB5dGhvbjgiLCJleHAiOjE1MjgxODI2MzQsImVtYWlsIjoiIn0.ejjVvEWxrBvbp18QIjQbL1TFE0c0ejQgizui_AROlAU"
}
返回值类型是否必须说明
usernamestr用户名
user_idint用户id
tokenstr身份认证凭据

3. 后端实现

Django REST framework JWT提供了登录签发JWT的视图,可以直接使用

from rest_framework_jwt.views import obtain_jwt_tokenurlpatterns = [url(r'^authorizations/$', obtain_jwt_token),
]

但是默认的返回值仅有token,我们还需在返回值中增加username和user_id。

通过修改该视图的返回值可以完成我们的需求。

在users/utils.py 中,创建

def jwt_response_payload_handler(token, user=None, request=None):"""自定义jwt认证成功返回数据"""return {'token': token,'user_id': user.id,'username': user.username}

修改配置文件

# JWTJWT_AUTH = {'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),'JWT_RESPONSE_PAYLOAD_HANDLER': 'users.utils.jwt_response_payload_handler',
}

4. 增加支持用户名与手机号均可作为登录账号

JWT扩展的登录视图,在收到用户名与密码时,也是调用Django的认证系统中提供的authenticate()来检查用户名与密码是否正确。

我们可以通过修改Django认证系统的认证后端(主要是authenticate方法)来支持登录账号既可以是用户名也可以是手机号。

修改Django认证系统的认证后端需要继承django.contrib.auth.backends.ModelBackend,并重写authenticate方法。

authenticate(self, request, username=None, password=None, **kwargs)方法的参数说明:

  • request 本次认证的请求对象
  • username 本次认证提供的用户账号
  • password 本次认证提供的密码

我们想要让用户既可以以用户名登录,也可以以手机号登录,那么对于authenticate方法而言,username参数即表示用户名或者手机号。

重写authenticate方法的思路:

  1. 根据username参数查找用户User对象,username参数可能是用户名,也可能是手机号
  2. 若查找到User对象,调用User对象的check_password方法检查密码是否正确

在users/utils.py中编写:

def get_user_by_account(account):"""根据帐号获取user对象:param account: 账号,可以是用户名,也可以是手机号:return: User对象 或者 None"""try:if re.match('^1[3-9]\d{9}$', account):# 帐号为手机号user = User.objects.get(mobile=account)else:# 帐号为用户名user = User.objects.get(username=account)except User.DoesNotExist:return Noneelse:return userclass UsernameMobileAuthBackend(ModelBackend):"""自定义用户名或手机号认证"""def authenticate(self, request, username=None, password=None, **kwargs):user = get_user_by_account(username)if user is not None and user.check_password(password):return user

在配置文件中告知Django使用我们自定义的认证后端

AUTHENTICATION_BACKENDS = ['users.utils.UsernameMobileAuthBackend',
]

5. 前端代码

修改login.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
<html xmlns=" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"><title>美多商城-登录</title><link rel="stylesheet" type="text/css" href="css/reset.css"><link rel="stylesheet" type="text/css" href="css/main.css"><script type="text/javascript" src="js/host.js"></script><script type="text/javascript" src="js/vue-2.5.16.js"></script><script type="text/javascript" src="js/axios-0.18.0.min.js"></script>
</head>
<body><div class="login_top clearfix"><a href="index.html" class="login_logo"><img src="images/logo02.png"></a>    </div><div class="login_form_bg" id='app'><div class="login_form_wrap clearfix"><div class="login_banner fl"></div><div class="slogan fl">商品美 · 种类多 · 欢迎光临</div><div class="login_form fr"><div class="login_title clearfix"><a href="javascript:;" class="cur">账户登录</a></div><div class="form_con"><div class="form_input cur"><form id="login-form" @submit.prevent="on_submit"><input type="text" v-model="username" @blur="check_username" name="" class="name_input" placeholder="请输入用户名或手机号"><div v-show="error_username" class="user_error" v-cloak>请填写用户名或手机号</div><input type="password" v-model="password" @blur="check_pwd" name="pwd" class="pass_input" placeholder="请输入密码"><div v-show="error_pwd" class="pwd_error" v-cloak>{{ error_pwd_message }}</div><div class="more_input clearfix"><input type="checkbox" v-model="remember"> <label>记住登录</label><a href="/find_password.html">忘记密码</a></div><input type="submit" name="" value="登 录" class="input_submit"></form></div></div><div class="third_party"><a @click="qq_login" class="qq_login"></a><a href="#" class="weixin_login">微信</a><a href="/register.html" class="register_btn">立即注册</a></div></div></div></div><div class="footer no-mp"><div class="foot_link"><a href="#">关于我们</a><span>|</span><a href="#">联系我们</a><span>|</span><a href="#">招聘人才</a><span>|</span><a href="#">友情链接</a>        </div><p>CopyRight © 2016 北京美多商业股份有限公司 All Rights Reserved</p><p>电话:010-****888    京ICP备*******8号</p></div><script type="text/javascript" src="js/login.js"></script>
</body>
</html>

在js目录中新建login.js

var vm = new Vue({el: '#app',data: {host: host,error_username: false,error_pwd: false,error_pwd_message: '请填写密码',username: '',password: '',remember: false},methods: {// 获取url路径参数    get_query_string: function(name){ var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');var r = window.location.search.substr(1).match(reg);if (r != null) {return decodeURI(r[2]);}return null;},// 检查数据check_username: function(){if (!this.username) {this.error_username = true;} else {this.error_username = false;}},check_pwd: function(){if (!this.password) {this.error_pwd_message = '请填写密码';this.error_pwd = true;} else {this.error_pwd = false;}},// 表单提交on_submit: function(){this.check_username();this.check_pwd();if (this.error_username == false && this.error_pwd == false) {axios.post(this.host+'/authorizations/', {username: this.username,password: this.password}, {responseType: 'json',withCredentials: true}).then(response => {// 使用浏览器本地存储保存tokenif (this.remember) {// 记住登录sessionStorage.clear();localStorage.token = response.data.token;localStorage.user_id = response.data.user_id;localStorage.username = response.data.username;} else {// 未记住登录localStorage.clear();sessionStorage.token = response.data.token;sessionStorage.user_id = response.data.user_id;sessionStorage.username = response.data.username;}// 跳转页面var return_url = this.get_query_string('next');if (!return_url) {return_url = '/index.html';}location.href = return_url;}).catch(error => {if (error.response.status == 400) {this.error_pwd_message = '用户名或密码错误';} else {this.error_pwd_message = '服务器错误';}this.error_pwd = true;})}},// qq登录qq_login: function(){}}
});

登录

登录,亦即我们所说的第三方登录,是指用户可以不在本项目中输入密码,而直接通过第三方的验证,成功登录本项目。

若想实现登录,需要成为互联的开发者,审核通过才可实现。注册方法可参考链接[

成为互联开发者后,还需创建应用,即获取本项目对应与互联的应用ID,创建应用的方法参考链接[

登录开发文档连接[

使用登录的流程

登录时序图

创建模型类

创建一个新的应用oauth,用来实现第三方认证登录。总路由前缀 oauth/

meiduo/meiduo_mall/utils/models.py文件中创建模型类基类,用于增加数据新建时间和更新时间。

from django.db import modelsclass BaseModel(models.Model):"""为模型类补充字段"""create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")class Meta:abstract = True  # 说明是抽象模型类, 用于继承使用,数据库迁移时不会创建BaseModel的表

在oauth/models.py中定义身份(openid)与用户模型类User的关联关系

from django.db import models
from meiduo_mall.utils.models import BaseModelclass OAuthUser(BaseModel):"""登录用户数据"""user = models.ForeignKey('users.User', on_delete=models.CASCADE, verbose_name='用户')openid = models.CharField(max_length=64, verbose_name='openid', db_index=True)class Meta:db_table = 'tb_oauth_qq'verbose_name = '登录用户数据'verbose_name_plural = verbose_name

进行数据库迁移

python manage.py makemigrations
python manage.py migrate

urllib使用说明

在后端接口中,我们需要向服务器发送请求,查询用户的信息,Python提供了标准模块urllib可以帮助我们发送http请求。

  • urllib.parse.urlencode(query)

将query字典转换为url路径中的查询字符串

  • urllib.parse.parse_qs(qs)

将qs查询字符串格式数据转换为python的字典

  • urllib.request.urlopen(url, data=None)

发送http请求,如果data为None,发送GET请求,如果data不为None,发送POST请求

返回response响应对象,可以通过read()读取响应体数据,需要注意读取出的响应体数据为bytes类型

返回登录网址的视图

1. 后端接口设计:

请求方式: GET /oauth/qq/authorization/?next=xxx

请求参数: 查询字符串

参数名类型是否必须说明
nextstr用户登录成功后进入美多商城的哪个网址

返回数据: JSON

{"login_url": "
}
返回值类型是否必须说明
login_urlstrqq登录网址

在配置文件中添加关于登录的应用开发信息

# 登录参数_CLIENT_ID = '101474184'
_CLIENT_SECRET = 'c6ce949e04e12ecc909ae6a8b09b637c'
_REDIRECT_URI = '
_STATE = '/'

新建oauth/utils.py文件,创建登录辅助工具类

from urllib.parse import urlencode, parse_qs
from urllib.request import urlopen
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, BadData
from django.conf import settings
import json
import loggingfrom . import constantslogger = logging.getLogger('django')class OAuth(object):"""认证辅助工具类"""def __init__(self, client_id=None, client_secret=None, redirect_uri=None, state=None):self.client_id = client_id or settings._CLIENT_IDself.client_secret = client_secret or settings._CLIENT_SECRETself.redirect_uri = redirect_uri or settings._REDIRECT_URIself.state = state or settings._STATE  # 用于保存登录成功后的跳转页面路径def get_qq_login_url(self):"""获取qq登录的网址:return: url网址"""params = {'response_type': 'code','client_id': self.client_id,'redirect_uri': self.redirect_uri,'state': self.state,'scope': 'get_user_info',}url = ' + urlencode(params)return url

在oauth/views.py中实现视图

#  url(r'^qq/authorization/$', views.AuthURLView.as_view()), class AuthURLView(APIView):"""获取登录的url"""def get(self, request):"""提供用于qq登录的url"""next = request.query_params.get('next')oauth = OAuth(state=next)login_url = oauth.get_qq_login_url()return Response({'login_url': login_url})

2. 前端

修改login.js,在methods中增加qq_login方法

// qq登录qq_login: function(){var next = this.get_query_string('next') || '/';axios.get(this.host + '/oauth/qq/authorization/?next=' + next, {responseType: 'json'}).then(response => {location.href = response.data.login_url;}).catch(error => {console.log(error.response.data);})}

未完待续, 同学们请等待下一期

全套笔记资料代码移步: 前往gitee仓库查看

感兴趣的小伙伴可以自取哦,欢迎大家点赞转发~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/599271.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【大数据】安装hive-3.1.2

1、上传HIVE包到/opt/software目录并解压到/opt/modules/ tar -zxvf apache-hive-3.1.2-bin.tar.gz -C /opt/modules/ 2、修改路径 mv /opt/modules/apache-hive-3.1.2-bin/ /opt/modules/hive 3、将hIVE下的bin目录加入到/etc/profile中 export HIVE_HOME/opt/module…

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之四 简单视频倒放效果

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之四 简单视频倒放效果 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之四 简单视频倒放效果 一、简单介绍 二、简单视频倒放效果实现原理 三、简单视频倒放效果案例实现…

牛客论坛项目中使用到Redis的地方总结

实体分为很多类&#xff0c;实体的确定要通过实体类型和实体id两个属性同时确定。牛客论坛中使用到了3类实体&#xff1a; 1 登录 使用到的Redis命令&#xff1a; set key value // 设置指定key的值为value get key // 获取指定key的值1.1 存储/获取验证码 验证码文本&…

Android匿名共享内存(Ashmem)

在Android中我们熟知的IPC方式有Socket、文件、ContentProvider、Binder、共享内存。其中共享内存的效率最高&#xff0c;可以做到0拷贝&#xff0c;在跨进程进行大数据传输&#xff0c;日志收集等场景下非常有用。共享内存是Linux自带的一种IPC机制&#xff0c;Android直接使用…

最优算法100例之35-整数1出现的次数

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 求出从0到任意非负整数中1出现的次数。 题解报告 求出从0到任意非负整数中1出现的次数。 模拟题,理清楚思路,不要有遗漏。…

隐私计算实训营第七讲-隐语SCQL的开发实践

隐私计算实训营第七讲-隐语SCQL的开发实践 文章目录 隐私计算实训营第七讲-隐语SCQL的开发实践1.如何使用SCQL&#xff1f;2.使用流程3.SCQL部署4.SCQL使用示例4.1创建用户4.2创建项目&用户授权4.3创建表4.4设置CCL4.5发起联合分析查询 1.如何使用SCQL&#xff1f; 2.使用流…

【C#】读取指定XML节点

&#x1f4f0;XML文件 <?xml version"1.0" encoding"utf-8"?> <configuration><userSettings><Internal.Settings type"Desktop"><setting name"StatsDisplayCount" serializeAs"String">…

DSOX3034T是德科技DSOX3034T示波器

181/2461/8938产品概述&#xff1a; 特点: 带宽:350 MHz频道:4存储深度:4 Mpts采样速率:5 GSa/s更新速率:每秒1000000个波形波形数学和FFT自动探测接口用于连接、存储设备和打印的USB主机和设备端口 触摸: 8.5英寸电容式触摸屏专为触摸界面设计 发现: 业界最快的无损波形更…

[dvwa] Command Injection

命令注入 0x01 low 没有过滤&#xff0c;直接利用 127.0.0.1 && ip a 函数 php_uname(mode) 动态地检查服务器的操作系统 ‘s’&#xff1a;操作系统名称 ‘n’&#xff1a;网络主机名 ‘r’&#xff1a;操作系统发行版本号 ‘v’&#xff1a;操作系统版本 ‘m’&…

Sharding Sphere JDBC使用Mybatis的saveBatch无法返回主键的问题

问题背景 项目中使用了MybatisPlus框架&#xff0c;数据库是PostgreSQL&#xff0c;配置了主键自增&#xff0c;新增数据后返回主键到实体类中。 项目中因为数据量问题&#xff0c;需要用到分库分表&#xff0c;因此引入了Sharding Sphere JDBC框架。但是Sharding Sphere JDB…

uniapp 密码框的眼睛

效果展示&#xff1a; uniapp input 官网链接&#xff1a;链接 按照官方文档&#xff0c;uni-icon出不来。 通过自己的方法解决了&#xff0c;解决方案如下&#xff1a; 代码&#xff1a; <uni-forms-item name"password"><inputclass"uni-input&quo…

机器学习——模型融合:平均法

机器学习——模型融合&#xff1a;平均法 在机器学习领域&#xff0c;模型融合是一种通过结合多个基本模型的预测结果来提高整体模型性能的技术。模型融合技术通常能够降低预测的方差&#xff0c;提高模型的鲁棒性&#xff0c;并在一定程度上提高预测的准确性。本文将重点介绍…