美多商城项目(二)

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 美多商城项目(二)

每日分享

  1. What you seek is seeking you.

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


美多商城项目(二)

1.注册信息的保存

1.1 接口设计

创建一个新用户

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

注册用户信息的保存

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

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

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

1.2注意小点

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

write-only  只在反序列化时使用
read-only    只在序列化时使用

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

2.补充验证:

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

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

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

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

2.JWT认证机制

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

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

2.3JWT 扩展

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

3.用户登录

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

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

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

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

2.认证系统中的 authenticate

  1. from django.contrib.auth import authenticate

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

3.Django认证后端类

from django.contrib.auth.backends import ModelBackend

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

自定义Django认证后端类:

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

指定Django认证后端类:

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中。

相关文章
|
6月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的博物馆展览与服务一体化平台的详细设计和实现
基于SpringBoot+Vue的博物馆展览与服务一体化平台的详细设计和实现
54 0
|
7月前
|
小程序 关系型数据库 MySQL
Gitee项目分享——学之思开源考试系统,食堂大妈看完都学会了
Gitee项目分享——学之思开源考试系统,食堂大妈看完都学会了
|
7月前
|
安全 Java 关系型数据库
社区团购|生鲜团购|基于Springboot+Vue实现前后端分离社区团购
社区团购|生鲜团购|基于Springboot+Vue实现前后端分离社区团购
159 0
|
Linux 数据库 文件存储
美多商城项目(六)
美多商城项目(六)
|
存储 NoSQL 前端开发
美多商城项目(八)
美多商城项目(八)
|
SQL NoSQL 关系型数据库
美多商城项目(九)
美多商城项目(九)
|
应用服务中间件 API 数据库
美多商城项目(十)
美多商城项目(十)
|
存储 搜索推荐 NoSQL
美多商城项目(七)
美多商城项目(七)
|
存储 Shell 数据库
美多商城项目(四)
美多商城项目(四)
|
API 数据库 数据安全/隐私保护
美多商城项目(三)
美多商城项目(三)

热门文章

最新文章