美多商城前三天重点内容大盘点

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 美多商城前三天重点内容大盘点

每日分享

  1. Thisis your life.Do what you love,anddo it often.

你自己的人生,要经常做你喜欢的事情。不要让其他人左右打扰你的人生。


美多商城前三天重点内容大盘点

文章导航

1.自定义Django认证系统用户模型类

2.跨域请求

3.celery异步任务发短信

4.JWT认证机制

5.自定义jwt扩展登录视图响应数据函数

6.自定义Django认证后端类(登录账户支持用户名和手机号)

7.QQ登录开发流程(流程图,可以自己画一下)

1.自定义Django认证系统用户模型类

1.1Django自带模型类介绍

Django中其实提供了用户模型类User保存用户的数据,让我们先来看一下自带的模型类都包含了些什么:

1.它包含了我们最常用的一些字段,如:username、password、email、isstaff(是否可以访问admin站点)、isactive(用户的账号是否激活)、issuperuser(是不是拥有超级管理员权限)、lastlogin(用户最后的登录时间)、datejoined(账户的创建时间)、firstname、last_name。

2.还有常用的方法:

set_password(raw_password)设置用户密码,将用户输入的明文密码进行hash转换。

check_password(raw_password)如果传入的明文密码是正确的返回True,和上面的配合使用。

上面的虽然很好,但是并不适用于特殊情况,比如我们在项目中需要定义一个手机号的字段,我们可以继承Django自带的模型类,然后扩展我们需要的字段即可。Django提供的用户模型类是 django.contrib.auth.models.AbstractUser,我们导入便可使用。

1.2自定义用户模型类步骤

我们在编写子应用的目录apps中创建Django应用users,并在配置文件中注册users应用。

在创建好的应用models.py中定义用户的用户模型类。

class User(AbstractUser):
    """用户模型类"""
    mobile = models.CharField(max_length=11, unique=True, verbose_name='手机号')
    class Meta:
        db_table = 'tb_users'
        verbose_name = '用户'
        verbose_name_plural = verbose_name

我们自定义的用户模型类还不能直接被Django的认证系统所识别,需要在配置文件中告知Django认证系统使用我们自定义的模型类。

在配置文件中进行设置

# AUTH_USER_MODEL = '子应用.模型类'
AUTH_USER_MODEL = 'users.User'

注意:我们对于AUTHUSERMODEL参数的设置一定要在第一次数据库迁移之前就设置好,否则后续使用可能出现未知错误。

执行数据库迁移

python manage.py makemigrations
python manage.py migrate

2.跨域请求

其实跨域请求很简单,就是源请求地址和被请求地址不是同源(同源地址要求两个url地址的IP、端口和协议完全一致),这个请求就是跨域请求

在美多商城项目中,注册页面,我们填写了手机号获取短信验证码的时候,就是一个跨域请求。前端页面是http://www.meiduo.site:8080/register.html,而点击获取短信验证码按钮的时候,要访问后端的接口http://api.meiduo.site:8000/sms_codes/13188888888/。协议相同;IP其实也是相同的,虽然我们设置的不一样,但是他们指向的ip都是127.0.0.1;但是端口号不一样,前端访问的是8080,后端设置的端口是8000。其中前端的页面就是源请求地址,后端的页面就是被请求地址

注意:浏览器在发起ajax跨域请求时,会有CORS跨域请求的限制。其他的形式,比如图片跳转地址或者表单提交的地址,在跨域请求的时候没有限制。CSRF跨站请求也是跨域请求。

在发起跨域请求时,在请求中携带一个请求头:

Origin:源请求地址

被请求的服务器在返回响应时,如果允许源地址对其进行跨域请求,需要在响应时携带一个响应头:

Access-Control-Allow-Origin:源请求地址

浏览器如果发现被请求的服务器在返回响应时,没有携带 Access-Control-Allow-Origin:源请求地址响应头,浏览器会直接将请求驳回,然后进行报错。

2.1使用

安装

pip install django-cors-headers

添加应用

INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)

中间件设置

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    ...
]

添加白名单

# CORS
CORS_ORIGIN_WHITELIST = (
    '127.0.0.1:8080',
    'localhost:8080',
    'www.meiduo.site:8080',
)
CORS_ALLOW_CREDENTIALS = True  # 允许携带cookie

凡是出现在白名单中的域名,都可以访问后端接口

CORSALLOWCREDENTIALS 指明在跨域访问中,后端是否支持对cookie的操作。

3.celery异步任务发短信

3.1原过程

客户端向服务器请求获取短信验证码,服务器中调用了一个方法 send_template_sms然后向第三方云通讯发送了一个请求,请求云通讯发送短信,云通讯返回给服务器一个响应,最后服务器向客户端返回响应。

3.2问题

上面的问题就是,如果网络差,我们服务器向云通讯发送请求后,服务器长时间得不到回应,那么也没法给客户端返回响应,最直观的现象就是,前端页面的获取短信验证码按钮没有出现倒计时。有可能一直等待,用户不知道啊,用户会以为没有发送短信验证码,然后疯狂点,最后那么用户体验贼差,这网站还开不开,气走了上帝,流失了客户,损失多么惨重。

3.3celery发短信

概念

1.任务执行者( worker):提前创建的进程

2.任务发出者:发出任务信息,让执行者去调用某个函数( 任务函数)

3.中间人( broker):存放任务消息。

本质:通过提前创建的进程调用函数来实现异步的任务。

创建的进程可以在不同的服务器上。

特点

1.任务执行者的进程可以单独在其他电脑上进行创建。

2.中间人又叫做任务队列,先添加到队列中的任务消息会先被worker所执行。

3.生产者-消费者模型。

注意:中间人可以是rabbit-mq,也可以是redis,我们使用redis。

发短信的过程

这个过程就变成了:当用户点击了发送短信验证码的时候,客户端向服务器发送了一个请求来获取短信验证码,服务器立马向客户端返回响应(其实启动了异步任务,请求第三方发送短信验证码,正因为是异步,所以服务器不需等待云通讯的响应即可去干另一件事,就是向客户端返回响应),客户端开始倒计时。我们设置了60秒的等待时间,足以弥补网络的延迟。

3.4使用

1.安装

pip install celery

2.创建一个Celery类的对象并进行配置,是为了配置中间人的地址。

# main.py
from celery import Celery
# 创建Celery类的对象
celery_app = Celery('demo')
# 加载配置
celery_app.config_from_object('配置文件的包路径')
# config.py
# 设置中间人地址borker
# broker_url = 'redis://<host>:<port>/<db>'
broker_url = 'redis://127.0.0.1:6379/3'

3.封装任务函数

@celery_app.task(name='send_sms_code')
def send_sms_code(a,b):
    # ...
    pass

4.启动celery的worker( 创建工作的进程)特别重要,我们每次开始都需要启动。

celery -A 'celery_app对象所在文件包路径' worker -l <日志级别>

日志级别:critial fatal、error、warn、info、debug

5.发出任务消息

send_sms_code.delay()

4.JWT认证机制

4.1session认证机制:

用户登录:
1.接收参数并进行校验(将用户名和密码校验)
2.检验用户名和密码是否正确
3.保存用户的登录信息
    session['user_id'] = 2
    session['username'] = 'ethanyan'
    session['mobile'] = '13288888888'
4.返回应答,登录成功

在返回应答时,会让客户端保存cookie和sessionid( 客户端session信息标识),在之后客户端访问服务器时,就会携带sessionid,服务器就可以根据sessionid取出对应的session信息并对用户登录的状态进行判断。

session认证机制存在问题:

a.session数据存储服务器,如果登录用户过多,会过多占用服务器存储空间。

b.session是依赖于cookie的,如果cookie被截获,可能会造成CSRF伪造。

c.对于分布式网站应用中,如果session存储在内存中,session的共享会产生问题。(在网站部署的时候,有很多服务器运行着,某台服务器内存中存着一位用户的session,其他服务器中是没有的。Nginx在转发的时候,有可能下次交给了其他服务器处理该用户的请求,然后就没有了给用户的一些信息,比如登录状态。)

优点:

a.存储在session中数据更加安全

4.2JWT认证机制

用户登录:
1.接收参数并进行校验(将用户名和密码校验)
2.检验用户名和密码是否正确
3.由服务器生成一个字符串(jwt token),保存了登录用户的身份信息
    公安局(服务器)--->身份证(jwt token)
4.返回响应时,需要将jwt token返回给客户端

客户端需要将jwt token保存下来,然后在请求服务器时,如果需要对用户的身份进行认证,客户端则需要将jwt token传递给服务器,由服务器对jwt token进行校验,来对用户进行认证。

优点:

a.jwt token是由客户端进行保存的,不会占用服务器存储空间。

缺点:

a.因为jwt token是存储在客户端,所以jwt token不建议存放一些敏感数据。

jwt token字符串格式:

是一个字符串,由三部分组成,用 .隔开

a.header(头部)

{
    "token类型",
    "signature签名加密算法",
}

使用base64对头部信息进行加密( 编码),加密之后生成的字符串就是header内容。

b.payload(载荷)

存储的是有效数据

{
    "user_id":"用户id",
    "username":"用户名",
    "email":"邮箱",
    "exp":"token有效时间" 
    ...
}

上面的exp(token有效期)是UTC时间,我们采用的北京时间相比是领先8个小时的。

使用base64对载荷信息进行加密( 编码),加密之后生成的字符串就是payload内容。

c.signature(签名)

作用:防止将jwt token被伪造

1.签名的生成过程

:服务器在生成jwt token时,会将header和payload字符串进行拼接,用 .隔开,然后使用一个只有服务器知道的密钥对拼接后的内容进行加密,加密之后生成的字符串就是signature内容。

2.签名验证过程?

:当客户端将jwt token传递给服务器之后,服务器首先需要进行签名认证,签名验证的过程:

  • 将客户端传递的jwt token中的header和payload字符串进行拼接,用 .隔开
  • 使用服务器之间的密钥对拼接之后的字符串进行加密
  • 将加密之后的内容和将客户端传递的jwt token中signature进行对比,如果不一致,就说明jwt token是被伪造的。

注意点

a.payload不要存放一些敏感数据

b.服务器密钥需要保持好,

c.如果可以,使用HTTPS协议。

5.自定义jwt扩展登录视图响应数据函数

jwt扩展中提供了一个登录视图 obtain_jwt_token这个登录视图就是接收username和password,并对账户名和密码进行校验,校验通过之后会生成一个jwt token,并在响应时返回。

自定义jwt扩展登录视图相应数据的函数

def jwt_response_payload_handler(token,user=None,request=None):
    """
    自定义jwt扩展登录视图的响应数据函数
    """
    return {
        'user_id':user.id,
        'username':user.username,
        'token':token
    }

配置

# JWT扩展配置
JWT_AUTH = {
    # 设置JWT的有效时间
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
    # 指定jwt扩展登录视图响应数据函数
    'JWT_RESPONSE_PAYLOAD_HANDLER':
    'users.utils.jwt_response_payload_handler'
}

6.自定义Django认证后端类(登录账户支持用户名和手机号)

1. obtain_jwt_token登录视图中没有自己实现账户名和密码校验的代码,而是调用了Django认证系统中一个函数进行账户和密码的校验。

2.认证系统中的 authenticate

  1. from django.contrib.auth import authenticate

authenticate方法内容也没有自己实现账户和密码校验的代码,而是调用Django认证后端类中 authenticate进行账户和密码的校验。

3.Django认证后端类

  1. from django.contrib.auth.backends importModelBackend

ModelBackend类中 authenticate最终实现了账户和密码校验代码,但是账户仅支持用户名。


自定义Django认证后端类:

class UsernameModelAuthBackend(ModelBackend):
    def authenticate(self,request,username=None,password=None,**kwargs):
        """
        username既可以传递用户名也可以传递手机号
        username:用户名或者手机号
        password:密码
        """
        # 根据用户名或手机号查询用户的信息
        pass
        # 如果用户存在,再校验密码
        pass

指定Django认证后端类:

  1. AUTHENTICATION_BACKENDS =['自定义Django认证后端类']

7.QQ登录开发流程(流程图,可以自己画一下)

1.客户端请求获取QQ登录网址。

2.我们自己服务器返回QQ登录网址和参数给客户端。

3.客户端请求QQ登录网址。

4.QQ服务器最终返回QQ授权登录页面。

5.用户授权登录QQ。

6.QQ服务器响应时让客户端重定向访问callback回调网址,并携带code和state参数。

7.浏览访问callback回调网址。客户端还向我们自己的服务器发起一个页面请求,获取QQ登录用户openid并处理,传递code。

8.我们自己的服务器凭code请求QQ服务器获取access_token。

9.qq服务器返回access_token。

10.我们自己的服务器凭access_token请求访问QQ服务器获取openid。

11.QQ服务器返回openid。

12.我们的服务器根据openid判断是否绑定过本网站用户(查一下我们数据库中的表)。

13.如果绑定过,我们的服务器直接签发jwt token并返回给客户端。

14.如果未绑定过,我们自己的服务器将openid加密并返回给客户端。

15.客户端请求绑定QQ登录用户。

16.我们自己的服务器保存绑定的数据。

17.我们自己的服务器签发jwt token并返回给客户端。

相关文章
|
6月前
|
测试技术 开发工具 UED
什么是农场游戏系统开发规则玩法/详细需求/案例详情/源码项目
明确定义游戏概念和目标**: - 确定农场游戏系统的主题和核心玩法,明确目标用户群体,并设定明确的游戏目标和规则。
|
6月前
|
安全 区块链
区块链农场游戏系统开发运营版/玩法详情/规则方案/案例设计/项目源码
Developing a blockchain farm game system is an interesting and challenging task. Here is a design solution that can help you get started developing such a system
|
6月前
|
存储 小程序 安全
东郊到家小程序系统开发|源码部署|案例详情
智能合约是基于区块链技术的一种计算机程序
|
18天前
|
小程序 vr&ar 数据安全/隐私保护
草料二维码|产品推广新利器,让客户快速获取最新产品信息
在数字化时代,信息的快速传递和便捷获取已成为商业竞争的关键。二维码,作为一种新兴的信息载体,正以其独特的优势在产品推广和客户服务中扮演着越来越重要的角色。本文为大家介绍了草料二维码的产品详情介绍模板,轻松搭建产品二维码。
|
3月前
|
前端开发 JavaScript NoSQL
构建苏宁商品详情页:从前端展示到后端服务的实战指南
苏宁商品详情页集成前端展示与后端服务,前端利用HTML/CSS/JavaScript呈现信息,后端采用Node.js/Java/Python等技术处理请求并从MySQL/MongoDB等数据库获取数据。示例中,Node.js通过Express框架搭建API,模拟商品查询逻辑。实际应用更为复杂,涵盖用户评价、推荐等功能,并需考虑分布式架构、安全防护及性能优化等方面。
构建苏宁商品详情页:从前端展示到后端服务的实战指南
|
6月前
|
新零售 人工智能 大数据
东郊到家预约服务系统开发|现成案例|模式详情
由于线下门店的商品陈列和消费者行为发生在物理空间里,线下门店想收集数据似乎没那么容易
|
6月前
|
新零售 人工智能 大数据
良久团购新零售系统模式开发|成熟技术|案例详情
由此看来,新零售是指利用大数据、人工智能等新兴技术,以满足顾客的需求为目标,将整个零售行业的产业链进行智能化升级。
|
6月前
|
新零售 供应链 搜索推荐
东郊到家预约项目系统开发源码|方案详情
实现产品个性化定制化柔性化生产,推动服务全面升级,为消费者构建“售前省心-售中用心-售后放心”
|
6月前
|
开发框架 监控 前端开发
家电预约服务系统开发步骤指南丨教程功能丨案例项目丨成熟技术丨源码详情
开发家电预约服务系统需要经历一系列步骤,包括规划、设计、开发、测试和部署
|
6月前
|
JavaScript 小程序 Java
基于Java的考编论坛网站的设计与实现(亮点:在线发布帖子、内容评论回复、购买二手物品、在线支付)
基于Java的考编论坛网站的设计与实现(亮点:在线发布帖子、内容评论回复、购买二手物品、在线支付)
49 0
基于Java的考编论坛网站的设计与实现(亮点:在线发布帖子、内容评论回复、购买二手物品、在线支付)