前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >美多商城前三天重点内容大盘点

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

作者头像
小闫同学啊
发布2019-07-18 14:41:22
7500
发布2019-07-18 14:41:22
举报
文章被收录于专栏:小闫笔记小闫笔记

每日分享

代码语言:javascript
复制
This is your life. Do what you love, and do 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中定义用户的用户模型类。

代码语言:javascript
复制
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认证系统使用我们自定义的模型类。

在配置文件中进行设置

代码语言:javascript
复制
# AUTH_USER_MODEL = '子应用.模型类'
AUTH_USER_MODEL = 'users.User'

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

执行数据库迁移

代码语言:javascript
复制
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使用

安装
代码语言:javascript
复制
pip install django-cors-headers
添加应用
代码语言:javascript
复制
INSTALLED_APPS = (
    ...
    'corsheaders',
    ...
)
中间件设置
代码语言:javascript
复制
MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    ...
]
添加白名单
代码语言:javascript
复制
# 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.安装

代码语言:javascript
复制
pip install celery

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

代码语言:javascript
复制
# main.py
from celery import Celery

# 创建Celery类的对象
celery_app = Celery('demo')

# 加载配置
celery_app.config_from_object('配置文件的包路径')
代码语言:javascript
复制
# config.py
# 设置中间人地址borker
# broker_url = 'redis://<host>:<port>/<db>'
broker_url = 'redis://127.0.0.1:6379/3'

3.封装任务函数

代码语言:javascript
复制
@celery_app.task(name='send_sms_code')
def send_sms_code(a,b):
    # ...
    pass

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

代码语言:javascript
复制
celery -A 'celery_app对象所在文件包路径' worker -l <日志级别>

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

5.发出任务消息

代码语言:javascript
复制
send_sms_code.delay()

4.JWT认证机制

4.1session认证机制:

代码语言:javascript
复制
用户登录:
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认证机制

代码语言:javascript
复制
用户登录:
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(头部)

代码语言:javascript
复制
{
    "token类型",
    "signature签名加密算法",
}

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

b.payload(载荷)

存储的是有效数据

代码语言:javascript
复制
{
    "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扩展登录视图相应数据的函数

代码语言:javascript
复制
def jwt_response_payload_handler(token,user=None,request=None):
    """
    自定义jwt扩展登录视图的响应数据函数

    """
    return {
        'user_id':user.id,
        'username':user.username,
        'token':token
    }

配置

代码语言:javascript
复制
# 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

代码语言:javascript
复制
from django.contrib.auth import authenticate

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

3.Django认证后端类

代码语言:javascript
复制
from django.contrib.auth.backends import ModelBackend

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

自定义Django认证后端类:

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

指定Django认证后端类:

代码语言:javascript
复制
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并返回给客户端。

优质文章推荐:

公众号使用指南

redis操作命令总结

前端中那些让你头疼的英文单词

Flask框架重点知识总结回顾

项目重点知识点详解

难点理解&面试题问答

flask框架中的一些常见问题

团队开发注意事项

浅谈密码加密

Django框架中的英文单词

Django中数据库的相关操作

DRF框架中的英文单词

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-01-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈技术精选 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 每日分享
  • 美多商城前三天重点内容大盘点
    • 文章导航
      • 1.自定义Django认证系统用户模型类
        • 1.1Django自带模型类介绍
        • 1.2自定义用户模型类步骤
      • 2.跨域请求
        • 2.1使用
      • 3.celery异步任务发短信
        • 3.1原过程
        • 3.2问题
        • 3.3celery发短信
        • 3.4使用
      • 4.JWT认证机制
        • 4.1session认证机制:
        • 4.2JWT认证机制
      • 5.自定义jwt扩展登录视图响应数据函数
        • 6.自定义Django认证后端类(登录账户支持用户名和手机号)
          • 7.QQ登录开发流程(流程图,可以自己画一下)
          相关产品与服务
          短信
          腾讯云短信(Short Message Service,SMS)可为广大企业级用户提供稳定可靠,安全合规的短信触达服务。用户可快速接入,调用 API / SDK 或者通过控制台即可发送,支持发送验证码、通知类短信和营销短信。国内验证短信秒级触达,99%到达率;国际/港澳台短信覆盖全球200+国家/地区,全球多服务站点,稳定可靠。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档