前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >美多商城项目(二)

美多商城项目(二)

作者头像
小闫同学啊
发布2019-07-18 11:40:07
1.1K0
发布2019-07-18 11:40:07
举报
文章被收录于专栏:小闫笔记小闫笔记

每日分享

代码语言:javascript
复制
What you seek is seeking you.

你所寻找的东西其实也正在寻找你。

美多商城项目(二)

1.注册信息的保存

1.1 接口设计

创建一个新用户

代码语言:javascript
复制
API: POST /users/
参数:
    {
        "username":"用户名",
        "password":"密码",
        "password2":"重复密码",
        "mobile":"手机号",
        "sms_code":"短信验证码",
        "allow":"是否同意用户协议", # 'true'同意
    }
响应:
    {
       'id':'用户ID',
       'username':'用户名',
       'mobile':'手机号',
       'token':'jwt token'
    }

注册用户信息的保存

1.获取参数进行校验(参数完整性,是否同意协议,手机号格式,手机号是否已经注册过,两次密码是否一致,短信验证码是否正确)

2.创建新用户并保存到数据库。

3.注册成功,将新用户序列化并返回。

1.2注意小点

1.序列化器类定义时的参数

代码语言:javascript
复制
write-only  只在反序列化时使用
read-only    只在序列化时使用

上面的 write-onlyread-only默认都是False,我们可以针对我们的需求对这两个参数进行设置。

2.补充验证:

a.在字段中添加 validators选项参数

b.对 <field_name>字段进行验证

c.在序列化器中需要同时对多个字段进行比较验证时,可以定义 validate方法来验证。

3.redis中存的数据,无论是什么格式,取出来的都是 bytes类型,所以按需求要进行解码 decode

2.JWT认证机制

2.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中数据更加安全

2.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协议。

2.3JWT 扩展

功能:生成jwt token,也能检验jwt token。

3.用户登录

代码语言:javascript
复制
API:POST /authorizations/
参数:
    {
        "username":"用户名",
        "password":"密码"
    }
响应:
    {
        "user_id":"用户ID",
        "username":"用户名",
        "token":"jwt token"
    }

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'
}

3.2登录账户支持手机号和用户名

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认证后端类']

3.2QQ登录

效果

当使用QQ账户登录的时候,会判断QQ账户和网站用户是否进行绑定,如果已经绑定过,则会直接让对应的用户登录成功;如果还没有绑定过,会先让用户进行绑定操作,只有绑定之后才能跳转到首页,登录成功。

预备工作

a.注册成功QQ的开发者。

b.登录开发者账户,创建开发者应用,提交相关的信息并等待审核。

c.审核通过,获取 appidappkey,就可以进行QQ相关功能开发。

开发关键点

a.QQ用户的 openid:QQ账户的唯一标识。

b.获取QQ登录用户的openid,判断openid和网站的用户是否进行了绑定,如果已经进行了绑定,直接让对应的用户登录成功;如果没有绑定,则将openid和对应网站用户进行绑定。

c.一个账户可以绑定多个QQ。如下示例:

id

openid

user_id

1

AFAJDFfjafjafjFADFJ123FFSA

2

2

DAFJFsfdafF3442JKKJfsadfaf

2

3.1小知识点

1.我们可以将JWT保存在cookie中,也可以保存在浏览器的本地存储里,我们保存在浏览器本地存储中。

2.浏览器的本地存储提供了sessionStorage 和 localStorage 两种:

  • sessionStorage 浏览器关闭即失效
  • localStorage 长期有效

3.『记住登录』这个小功能是在前端完成的。如果记住密码,就保存在localStorage中,不记住密码,就将其保存在sessionStorage中。

优质文章推荐:

公众号使用指南

redis操作命令总结

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

Flask框架重点知识总结回顾

项目重点知识点详解

难点理解&面试题问答

flask框架中的一些常见问题

团队开发注意事项

浅谈密码加密

Django框架中的英文单词

Django中数据库的相关操作

DRF框架中的英文单词

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 每日分享
  • 美多商城项目(二)
    • 1.注册信息的保存
      • 1.1 接口设计
      • 1.2注意小点
    • 2.JWT认证机制
      • 2.1session认证机制:
      • 2.2JWT认证机制
      • 2.3JWT 扩展
    • 3.用户登录
      • 3.2登录账户支持手机号和用户名
      • 3.2QQ登录
      • 3.1小知识点
相关产品与服务
访问管理
访问管理(Cloud Access Management,CAM)可以帮助您安全、便捷地管理对腾讯云服务和资源的访问。您可以使用CAM创建子用户、用户组和角色,并通过策略控制其访问范围。CAM支持用户和角色SSO能力,您可以根据具体管理场景针对性设置企业内用户和腾讯云的互通能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档