【Django开发】0到1美多商城项目md教程第7篇:登录,1. 互联开发者申请步骤【附代码文档】

美多商城完整教程(附代码资料)主要内容讲述:欢迎来到美多商城!,项目准备。展示用户注册页面,创建用户模块子应用。用户注册业务实现,用户注册前端逻辑。图形验证码,图形验证码接口设计和定义。短信验证码,避免频繁发送短信验证码。账号登录,用户名登录。登录,登录开发文档。用户基本信息,查询并渲染用户基本信息。收货地址,省市区三级联动。收货地址,展示地址前后端逻辑。商品数据库表设计,SPU和SKU。准备商品数据,容器化方案Docker。首页广告,展示首页商品频道分类。商品列表页,列表页面包屑导航。商品搜索,Haystack扩展建立索引。商品详情页,统计分类商品访问量。购物车管理,添加购物车。购物车管理,删除购物车。订单,结算订单。提交订单,使用乐观锁并发下单。对接系统,订单支付功能。页面静态化,首页广告页面静态化。MySQL读写分离,MySQL主从同步。

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

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


全套教程部分目录:


部分文件图片:

登录

登录开发文档

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

1. 互联开发者申请步骤

若想实现登录,需要成为互联的开发者,审核通过才可实现。

  • 相关连接:[

2. 互联应用申请步骤

成为互联开发者后,还需创建应用,即获取本项目对应与互联的应用ID。

  • 相关连接:[

3. 网站对接登录步骤

互联提供有开发文档,帮助开发者实现登录。

  • 相关连接:[

4. 登录流程分析

5. 知识要点

  1. 当我们在对接第三方平台的接口时,一定要认真阅读第三方平台提供的文档。文档中一定会有接口的使用说明,方便我们开发。

定义登录模型类

登录成功后,我们需要将用户和美多商场用户关联到一起,方便下次登录时使用,所以我们选择使用MySQL数据库进行存储。

1. 定义模型类基类

为了给项目中模型类补充数据创建时间更新时间两个字段,我们需要定义模型类基类。 在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的表

2. 定义登录模型类

创建一个新的应用oauth,用来实现第三方认证登录。

# oauthurl(r'^oauth/', include('oauth.urls')),

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

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

3. 迁移登录模型类

$ python manage.py makemigrations
$ python manage.py migrate

登录工具LoginTool

1. LoginTool介绍

  • 该工具封装了登录时对接互联接口的请求操作。可用于快速实现登录。

2. LoginTool安装

pip install LoginTool

3. LoginTool使用说明

1.导入

from LoginTool.tool import OAuth

2.初始化OAuth对象

oauth = OAuth(client_id=settings._CLIENT_ID, client_secret=settings._CLIENT_SECRET, redirect_uri=settings._REDIRECT_URI, state=next)

3.获取登录扫码页面,扫码后得到Authorization Code

login_url = oauth.get_qq_url()

4.通过Authorization Code获取Access Token

access_token = oauth.get_access_token(code)

5.通过Access Token获取OpenID

openid = oauth.get_open_id(access_token)

OAuth2.0认证获取openid

待处理业务逻辑

# 提取code请求参数# 使用code向服务器请求access_token# 使用access_token向服务器请求openid# 使用openid查询该用户是否在美多商城中绑定过用户# 如果openid已绑定美多商城用户,直接生成JWT token,并返回# 如果openid没绑定美多商城用户,创建用户并绑定到openid

1. 获取登录扫码页面

1.请求方式

选项方案
请求方法GET
请求地址/qq/login/
>
2.请求参数:查询参数
参数名类型是否必传说明
nextstring用于记录登录成功后进入的网址
>
3.响应结果:JSON
字段说明
code状态码
errmsg错误信息
login_url登录扫码页面链接
>
4.后端逻辑实现
class AuthURLView(View):"""提供登录页面网址"""def get(self, request):# next表示从哪个页面进入到的登录页面,将来登录成功后,就自动回到那个页面next = request.GET.get('next')# 获取登录页面网址oauth = OAuth(client_id=settings._CLIENT_ID, client_secret=settings._CLIENT_SECRET, redirect_uri=settings._REDIRECT_URI, state=next)login_url = oauth.get_qq_url()return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'login_url':login_url})

5.登录参数

_CLIENT_ID = '101518219'
_CLIENT_SECRET = '418d84ebdc7241efb79536886ae95224'
_REDIRECT_URI = '

2. 接收Authorization Code

提示:

  • 用户在登录成功后,会将用户重定向到我们配置的回调网址。
  • 在重定向到回调网址时,会传给我们一个Authorization Code
  • 我们需要拿到Authorization Code完成OAuth2.0认证获取openid
  • 在本项目中,我们申请登录开发资质时配置的回调网址为:

  • `

  • 互联重定向的完整网址为:

  • `

class AuthUserView(View):"""用户扫码登录的回调处理"""def get(self, request):"""Oauth2.0认证"""# 接收Authorization Codecode = request.GET.get('code')if not code:return http.HttpResponseForbidden('缺少code')pass
url(r'^oauth_callback/$', views.AuthUserView.as_view()),

3. OAuth2.0认证获取openid

  1. 使用code向服务器请求access_token
  2. 使用access_token向服务器请求openid
class AuthUserView(View):"""用户扫码登录的回调处理"""def get(self, request):"""Oauth2.0认证"""# 提取code请求参数code = request.GET.get('code')if not code:return http.HttpResponseForbidden('缺少code')# 创建工具对象oauth = OAuth(client_id=settings._CLIENT_ID, client_secret=settings._CLIENT_SECRET, redirect_uri=settings._REDIRECT_URI)try:# 使用code向服务器请求access_tokenaccess_token = oauth.get_access_token(code)# 使用access_token向服务器请求openidopenid = oauth.get_open_id(access_token)except Exception as e:logger.error(e)return http.HttpResponseServerError('OAuth2.0认证失败')pass

4. 本机绑定www.meiduo.site域名

1.ubuntu系统或者Mac系统

编辑 /etc/hosts

2.Windows系统

编辑 C:\Windows\System32\drivers\etc\hosts

openid是否绑定用户的处理

1. 判断openid是否绑定过用户

使用openid查询该用户是否在美多商城中绑定过用户。

try:oauth_user = OAuthUser.objects.get(openid=openid)
except OAuthUser.DoesNotExist:# 如果openid没绑定美多商城用户pass
else:# 如果openid已绑定美多商城用户pass

2. openid已绑定用户的处理

如果openid已绑定美多商城用户,直接生成状态保持信息,登录成功,并重定向到首页。

try:oauth_user = OAuthUser.objects.get(openid=openid)
except OAuthUser.DoesNotExist:# 如果openid没绑定美多商城用户pass
else:# 如果openid已绑定美多商城用户# 实现状态保持qq_user = oauth_user.userlogin(request, qq_user)# 响应结果next = request.GET.get('state')response = redirect(next)# 登录时用户名写入到cookie,有效期15天response.set_cookie('username', qq_user.username, max_age=3600 * 24 * 15)return response

3. openid未绑定用户的处理

  • 为了能够在后续的绑定用户操作中前端可以使用openid,在这里将openid签名后响应给前端。
  • openid属于用户的隐私信息,所以需要将openid签名处理,避免暴露。
try:oauth_user = OAuthUser.objects.get(openid=openid)
except OAuthUser.DoesNotExist:# 如果openid没绑定美多商城用户access_token = generate_eccess_token(openid)context = {'access_token': access_token}return render(request, 'oauth_callback.html', context)
else:# 如果openid已绑定美多商城用户# 实现状态保持qq_user = oauth_user.userlogin(request, qq_user)# 重定向到主页response = redirect(reverse('contents:index'))# 登录时用户名写入到cookie,有效期15天response.set_cookie('username', qq_user.username, max_age=3600 * 24 * 15)return response

oauth_callback.html中渲染access_token

<input v-model="access_token" type="hidden" name="access_token" value="{{ access_token }}">

4. 补充itsdangerous的使用

  • itsdangerous模块的参考资料链接 [
  • 安装:pip install itsdangerous

  • TimedJSONWebSignatureSerializer的使用

  • 使用TimedJSONWebSignatureSerializer可以生成带有有效期token

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from django.conf import settings# serializer = Serializer(秘钥, 有效期秒)serializer = Serializer(settings.SECRET_KEY, 300)# serializer.dumps(数据), 返回bytes类型token = serializer.dumps({'mobile': '18512345678'})
token = token.decode()# 检验token# 验证失败,会抛出itsdangerous.BadData异常serializer = Serializer(settings.SECRET_KEY, 300)
try:data = serializer.loads(token)
except BadData:return None

补充:openid签名处理

  • oauth.utils.py
def generate_eccess_token(openid):"""签名openid:param openid: 用户的openid:return: access_token"""serializer = Serializer(settings.SECRET_KEY, expires_in=constants.ACCESS_TOKEN_EXPIRES)data = {'openid': openid}token = serializer.dumps(data)return token.decode()

openid绑定用户实现

类似于用户注册的业务逻辑

  • 当用户输入的手机号对应的用户已存在

  • 直接将该已存在用户跟openid绑定

  • 当用户输入的手机号对应的用户不存在

  • 新建一个用户,并跟openid绑定

class AuthUserView(View):"""用户扫码登录的回调处理"""def get(self, request):"""Oauth2.0认证"""......def post(self, request):"""美多商城用户绑定到openid"""# 接收参数mobile = request.POST.get('mobile')pwd = request.POST.get('password')sms_code_client = request.POST.get('sms_code')access_token = request.POST.get('access_token')# 校验参数# 判断参数是否齐全if not all([mobile, pwd, sms_code_client]):return http.HttpResponseForbidden('缺少必传参数')# 判断手机号是否合法if not re.match(r'^1[3-9]\d{9}$', mobile):return http.HttpResponseForbidden('请输入正确的手机号码')# 判断密码是否合格if not re.match(r'^[0-9A-Za-z]{8,20}$', pwd):return http.HttpResponseForbidden('请输入8-20位的密码')# 判断短信验证码是否一致redis_conn = get_redis_connection('verify_code')sms_code_server = redis_conn.get('sms_%s' % mobile)if sms_code_server is None:return render(request, 'oauth_callback.html', {'sms_code_errmsg':'无效的短信验证码'})if sms_code_client != sms_code_server.decode():return render(request, 'oauth_callback.html', {'sms_code_errmsg': '输入短信验证码有误'})# 判断openid是否有效:错误提示放在sms_code_errmsg位置openid = check_access_token(access_token)if not openid:return render(request, 'oauth_callback.html', {'openid_errmsg': '无效的openid'})# 保存注册数据try:user = User.objects.get(mobile=mobile)except User.DoesNotExist:# 用户不存在,新建用户user = User.objects.create_user(username=mobile, password=pwd, mobile=mobile)else:# 如果用户存在,检查用户密码if not user.check_password(pwd):return render(request, 'oauth_callback.html', {'account_errmsg': '用户名或密码错误'})# 将用户绑定openidtry:OAuthUser.objects.create(openid=openid, user=user)except DatabaseError:return render(request, 'oauth_callback.html', {'qq_login_errmsg': '登录失败'})# 实现状态保持login(request, user)# 响应绑定结果next = request.GET.get('state')response = redirect(next)# 登录时用户名写入到cookie,有效期15天response.set_cookie('username', user.username, max_age=3600 * 24 * 15)return response

用户中心

用户基本信息

用户基本信息逻辑分析

1. 用户基本信息逻辑分析

以下是要实现的后端逻辑

  1. 用户模型补充email_active字段
  2. 查询并渲染用户基本信息
  3. 添加邮箱
  4. 发送邮箱验证邮件
  5. 验证邮箱

    提示:

  6. 用户添加邮箱时,界面的局部刷新,我们选择使用Vue.js来实现。

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

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

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

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

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

相关文章

HarmonyOS实战开发-自定义分享

介绍 自定义分享主要是发送方将文本&#xff0c;链接&#xff0c;图片三种类型分享给三方应用,同时能够在三方应用中展示。本示例使用数据请求 实现网络资源的获取&#xff0c;使用屏幕截屏 实现屏幕的截取&#xff0c;使用文件管理 实现对文件&#xff0c;文件目录的管理&…

地球上的七大洲介绍

地球上的七大洲示意图&#xff1a; 1. 亚洲&#xff08;Asia&#xff09;&#xff1a;世界上最大的洲&#xff0c;面积约为44579000平方公里。亚洲地域辽阔&#xff0c;包括从北极圈到赤道的各种气候和地形。它拥有世界上最多的人口&#xff0c;也是世界上一些最古老文明的发源…

transformer上手(4) —— 模型与分词器

1 模型 除了像之前使用 AutoModel 根据 checkpoint 自动加载模型以外&#xff0c;我们也可以直接使用模型对应的 Model 类&#xff0c;例如 BERT 对应的就是 BertModel&#xff1a; from transformers import BertModel model BertModel.from_pretrained("bert-base-ca…

28、链表-两数相加

思路&#xff1a; 有几个方面需要考虑 双指针遍历&#xff0c;如果出现和大于10那么向前进1如果长度不一样那么长的部分直接落下并且考虑进1 的问题 代码如下&#xff1a; class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {if (l1null||l2null){…

【40分钟速成智能风控14】数据处理和特征工程

目录 智能模型数据处理 重复值处理 一致性检验 数据交叉验证 线上线下验证 有效性检验 业务经验 数据分析 特征工程和特征筛选 探索性数据分析 字符型特征 缺失率过高 类别过少 异常值处理 智能模型数据处理 重复值处理 保证数据的唯一性也是数据清洗过程中需要…

金融机构与金融市场监管

金融机构与金融市场监管 中国的金融监管机构银行业监管的必要性银行业监管的基本目标银行业监管的基本内容商业银行的设立审批制度银行业日常监督管理流动性要求资产质量监管合理的内部控制制度风险集中和风险暴漏的监管银行资本风险资本的计算资本充足率的计算 中国的金融监管…

Hadoop+Spark大数据技术(微课版)曾国荪、曹洁版思维导图第四次作业 (第4章 HBase分布式DB)

1.简述Hbase的特点及与传统关系数据库的区别 HBase与传统关系数据库的区别 &#xff08;1&#xff09;数据类型 关系数据库具有丰富的数据类型&#xff0c;如字符串型、数值型、日期型、二进制型等。HBase只有字符串数据类型&#xff0c;数据的实际类型都是交由用户自己编写程序…

【JSON2WEB】14 基于Amis的CRUD开发30分钟速成

【JSON2WEB】系列目录 【JSON2WEB】01 WEB管理信息系统架构设计 【JSON2WEB】02 JSON2WEB初步UI设计 【JSON2WEB】03 go的模板包html/template的使用 【JSON2WEB】04 amis低代码前端框架介绍 【JSON2WEB】05 前端开发三件套 HTML CSS JavaScript 速成 【JSON2WEB】06 JSO…

【springCloud】版本学习

Spring Cloud介绍 官网地址&#xff1a;https://spring.io/projects/spring-cloud Spring Cloud 是一个基于 Spring Boot 的微服务架构解决方案&#xff0c;它提供了一系列工具和模式来帮助开发者构建分布式系统。Spring Cloud 的组件和模式包括配置管理、服务发现、断路器、…

1028: 特定字符序列的判断

解法&#xff1a; #include<iostream> #include<stack> using namespace std; int main() {stack<char> sk;char c;bool flag false;while (cin >> c) {if (c #) break;if (c ) {flag true;continue;}if (flag) {if (sk.top() c) {sk.pop();cont…

JavaScript知识点 --javaweb学习笔记

什么是Javascript? JavaScript(简称:JS)是一门跨平台、面向对象的脚本语言。是用来控制网页行为的&#xff0c;它能使网页可交互JavaScript 和Java 是完全不同的语言&#xff0c;不论是概念还是设计。但是基础语法类似JavaScript在1995 年由 Brendan Eich 发明&#xff0c;并…

【Spring Boot】深入解密Spring Boot日志:最佳实践与策略解析

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;【Spring Boot】深入解密Spring Boot日志&#xff1a;最佳实践与策略解析 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 Spring Boot 日志一. 日志的概念?…

OpenHarmony实战开发-FaultLoggerd组件。

简介 Faultloggerd部件是OpenHarmony中C/C运行时崩溃临时日志的生成及管理模块。面向基于 Rust 开发的部件&#xff0c;Faultloggerd 提供了Rust Panic故障日志生成能力。系统开发者可以在预设的路径下找到故障日志&#xff0c;定位相关问题。 架构 Native InnerKits 接口Sig…

汇舟问卷:国外问卷调查适合哪些人?

在这个快节奏的时代&#xff0c;朝九晚五的工作模式似乎已经成为许多人的固定生活模式。然而&#xff0c;这种日复一日的工作方式往往让人感到疲惫和厌倦&#xff0c;我们渴望找到一种既能赚钱又能兼顾生活的方式。 海外问卷调查作为一种适合在家做的赚钱方式&#xff0c;这两…

【Golang学习笔记】从零开始搭建一个Web框架(二)

文章目录 模块化路由前缀树路由 前情提示&#xff1a; 【Golang学习笔记】从零开始搭建一个Web框架&#xff08;一&#xff09;-CSDN博客 模块化路由 路由在kilon.go文件中导致路由和引擎交织在一起&#xff0c;如果要实现路由功能的拓展增强&#xff0c;那将会非常麻烦&…

基于Springboot+Vue的Java项目-课程作业管理系统(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

rocketmq面试

broker主从复制机制 同步复制&#xff1a; 等Master和Slave均写成功后&#xff0c;才反馈给客户端写成功状态&#xff1b; 如果Master出故障&#xff0c; Slave上有全部的备份数据&#xff0c;容易恢复&#xff0c;但是同步复制会增大数据写入延迟&#xff0c;降低系统吞吐量。…

使用LNMP部署动态网站环境

目录 实验环境 一、配置LNMP架构环境 二、验证部署的LNMP 动态网站环境是否可用 三、配置过程中遇到的问题及解决思路 实验环境 centos7 192.168.81.131/24 一、配置LNMP架构环境 概念及配置手册参考第20章 使用LNMP架构部署动态网站环境。 | 《Linux就该这么学》 安装g…

Java编程练习之接口的声明及实现

1.创建老师类和学生类&#xff0c;两个类都实现了问候接口和工作接口&#xff0c;模拟上课的场景&#xff0c;运行效果如下&#xff1a; package Zaria; interface hello{public void speak(); } interface work{public void dowork(); } class Student implements hello,work{…

gitee如何新建仓库并用小乌龟上传代码

目录 1.登录并注册gitee账号 2.创建新仓库 3.填写仓库信息 4.初始化本地仓库 5.上传数据 7.gitee官网查看上传文件 8.如何安装小乌龟 1.登录并注册gitee账号 2.创建新仓库 登录后&#xff0c;点击页面右上角的「」按钮&#xff0c;选择「新建仓库」。 3.填写仓库信息 …