完整电商项目--(十一)后台管理项目(drf)(1):CORS跨域与JWT

跨域CORS(跨域资源共享)

背景

  • 我们采用设计 后台管理系统,使用 django drf框架实现。并且前后端有两个不同的端口。
  • 前端和后端是 不同的域名,涉及到跨域访问数据的问题,因为浏览器的同源策略,默认是不支持两个不同域间相互访问数据,此时为解决这个问题,就需要在后端添加跨域访问的支持。

解决方案

  • options询问请求。这个就是用来判断是否 允许跨域访问数据的。 例如我们登录后台管理
    在这里插入图片描述
# 登陆操作时的请求

INFO basehttp 124 "OPTIONS /meiduo_admin/authorizations/ HTTP/1.1" 200 0
INFO basehttp 124 "POST /meiduo_admin/authorizations/ HTTP/1.1" 200 227

# 1.从pip安装:
python -m pip install django-cors-headers

# 2.然后将其添加到已安装的应用程序中:确保添加结尾逗号,否则可能会收到一个逗号ModuleNotFoundError
INSTALLED_APPS  = [
    ...
    ' corsheaders '...
]

# 3.您还需要添加一个中间件类来侦听响应:

MIDDLEWARE  = [
    ...
    的corsheaders。中间件。CorsMiddleware ',
     'django.middleware.common.CommonMiddleware'...
CorsMiddleware应该放置在尽可能高的位置,尤其是在任何可以生成响应的中间件之前,例如Django CommonMiddleware或Whitenoise WhiteNoiseMiddleware。如果不是以前,它将无法将CORS标头添加到这些响应中。

另外,如果您正在使用CORS_REPLACE_HTTPS_REFERER它,则应将其放置在Django之前CsrfViewMiddleware(请参见下文)。

根据中间价你执行顺序,直接放到第一个位置就可以了~
]

关于允许访问白名单:CORS_ALLOWED_ORIGINS

授权进行跨站点HTTP请求的来源列表。默认为[]。

Origin由CORS RFC第3.2节定义 为URI方案+主机名+端口,或特殊值“ null”或“ file//”之一。默认端口(HTTPS = 443,HTTP = 80)在此处是可选的。

浏览器在“隐私敏感的上下文”中(例如,当客户端从file://域中运行时)发送特殊值null 。根据此bug,特殊值file//是由Android上的某些版本的Chrome意外发送的。

例:

CORS_ALLOWED_ORIGINS  = [
     “ https://example.com”,
     “ https://sub.example.com”,
     “ http:// localhost:8080”,
     “ http://127.0.0.1:9000]
以前,此设置称为CORS_ORIGIN_WHITELIST,仍然可以用作别名,新名称优先。

允许互相访问cookie:CORS_ALLOW_CREDENTIALS

如果为True,则将允许将cookie包含在跨站点HTTP请求中。默认为False。

注意:在Django 2.1中,添加了SESSION_COOKIE_SAMESITE设置,'Lax'默认情况下设置为 ,这将防止Django的会话cookie跨域发送。更改它以None绕过此安全限制

token机制

想了解session机制的,可以看看我之前的文章

  • token机制是为了解决 session中暴露的一些缺点而学习的,所以可以先阅读前文

流程

1. 生成token

  • 进入登录页面,前端将用户输入的 账号和密码等信息传递到后端
  • 后验证通过之后, 如图片中,将用户数据进行加密(生成所谓的token),但是后端并不保存该数据!(和session的区别),而是将该 token字符串返回给前端

2. 前端存储token字符串

  • 前端在接收到后端返回的token数据之后,会进行存储。有两个存储空间。 一个是Local Storage,一个是Session Storage
    在这里插入图片描述
  • 前端可以通过js代码,将token信息,保存到Local Storage当中,也可以提取它。如下
    在这里插入图片描述
    在这里插入图片描述

3.将token携带再请求当中,交由后端验证

  • 前端发送请求的时候,带上这个token,发送给后端
  • 后端解密前端发送过来的 token。 对其进行判断
  • 整个过程中后端并不存储任何信息,而是有一套加密解密的方法,保证数据不被篡改,正确验证。并且节约服务器资源。
  • 也可以加密的过程中设置 加密的有效期,用来判断数据是否过期(解决 保存登录状态带时效的问题,比如登录之后七天内可以不用登陆,进入网站自动登录)。

注意

  • (1)当token 保存到 Storage中后,浏览器发送请求时想要携带这个token数据,只能通过js代码,读取到之后携带传递给后端。并不是向cookie一样(sessionid),发送任何请求都会携带。

  • (2)不同网站之间保存的数据 是不能用js代码 访问彼此的数据的!也就是说,当前的token,是保存在当前的域名下的存储空间里的(如上面图片例子),只能通过当前的js进行操作。

  • 当前的js代码也是在同个域名下的
    在这里插入图片描述

  • (3)上面的这种操作,保证了其他网站不能获取当前域名下的数据内容。(防止了其他网站 伪造了一段js代码,企图访问本网站下的数据,基于域名安全,只有该域名下的js代码才可以访问)。也就是说 资源存储域名(js,css啥的通俗讲),数据存储域名 是一致的。

  • (4) 同样是 有一套加密解密的方法,所以 任何服务器都能对 token数据进行验证,这就解决的 服务器拓展的问题

以上所述,就是解决了session机制的三个缺点:占用服务器端资源空间(存储session数据),csrf攻击(cookie只要发送请求就会携带,容易泄露信息),集群搭建的问题(拓展服务器)

JWT(Json Web Token) 基于token的鉴权机制

基本流程

  • 用户使用用户名密码来请求服务器
  • 服务器进行验证用户的信息
  • 服务器通过验证发送给用户一个token
  • 客户端存储token,并在每次请求时附送上这个token值
  • 服务端验证token值,并返回数据

jwt的基本构成

  • 完整:
# JWT 加密后的随机字符串

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
  • 通过 . 将其分为三部分

(1)header

  • jwt的头部承载两部分信息:
    • 声明类型,这里是jwt
    • 声明加密的算法 通常直接使用 HMAC SHA256
      完整的头部信息类似这样:
{
    
    
  'typ': 'JWT',
  'alg': 'HS256'
}

然后将头部进行base64加密(该加密是可以对称解密的),构成了第一部分

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

payload

  • 载荷就是存放有效信息的地方,这些有效信息包含三个部分

    • 标准中注册的声明
    • 公共的声明
    • 私有的声明
  • 标准中注册的声明 (建议但不强制使用) :

    iss: jwt签发者
    sub: jwt所面向的用户
    aud: 接收jwt的一方
    exp: jwt的过期时间,这个过期时间必须要大于签发时间
    nbf: 定义在什么时间之前,该jwt都是不可用的.
    iat: jwt的签发时间
    jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

  • 公共的声明
    公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.

  • 私有的声明
    私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息

定义一个 payload:

{
    
    
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

signature

  • JWT的第三部分是一个签证信息,这个签证信息由三部分组成:

    • header (base64后的)
    • payload (base64后的)
    • secret
      这个部分需要base64加密后的header和base64加密后的payload使用 . 连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。

signature作用

  • 数据安全的保证,防止别人修改数据,因为前两部分数据都是常规加密很容易破解后修改,但是 signature签证信息的作用就体现出来了,第三部分只要 知道私钥后才可能被破解,只要你前两段信息和我的 签证信息不同,我就不承认,不给你验验通过,另外通过 signature的 解密设置时间,可以实现 一段时间的 登录状态保持。 解密失败,可能是因为过期,就导致失去登录状态。

加密介绍

  • (1) 首先要具有一套 加密算法
  • (2) 需要有加密数据
  • (3) 加密秘钥:保证数据的安全,没有这个秘钥 ,就不能进行解密操作。 类似之前QQ登录中讲过的 itsdangerous,也是需要秘钥。

好了,就先介绍到这里,这些就是基本的信息,下节介绍怎么在 drf中使用这个 jwt
over!

猜你喜欢

转载自blog.csdn.net/pythonstrat/article/details/108263297