前端鉴权方案

前端鉴权的背景

HTTP是无状态的,Http的请求方和响应方无法维护状态,都是一次性的。但是有的时候需要维护状态。

现代鉴权方案的根本原理就是:在服务端生成标记,在客户端或服务端保存标记,客户端在请求时带上标记,服务端校验客户端标识是否合法,再确定是否返回数据。以下5方法只是在细节上的差异。

  • cookie
  • Session
  • Token
  • JWT
  • 单点登录

Cookie是什么

cookie是服务器发送到用户浏览器并保存在本地的一小块数据,他会在浏览器下一次向同一服务器发起请求时被携带并发送到服务器上。

作用

  • 会话状态管理
  • 个性化设置
  • 浏览器行为跟踪(跟踪分析用户行为等)

优点

  • 自动携带发送,用户无感

缺点

  • 安全性能差,明文储存,不适合存放敏感信息
  • 大小有限制(一般为4kb),cookie的数量有限(一般一个站点最多20个),这对于复杂的存储需求来说是不够的
  • 可以被禁用,用户可以决定不在浏览器中使用cookie,可能会导致浏览器的运行产生过一些问题
  • 隐私问题,启用cookie的web浏览器可以跟踪你访问过的所有网站

配置

Domain/Path

Domain指定哪些域名的http请求需要携带cookie,默认为当前URL的一级域名。
Path属性指定哪些路径的htttp请求需要携带cookie。在domain属性校验通过的情况下,浏览器通过path针对特定路径的请求发送cookie

Expires/Max-age

Expires设置一个具体的浏览器时间,过期之后浏览器自动删除cookie。如果不设置,则浏览器关闭时,会话结束的时候,浏览器会自动删除cookie。当本地时间时间不精确的时候,则cookie的保存时间存在一定的误差。
Max-age属性指定从接受请求开始Cookie存在秒数,过了这个时间,浏览器就不保存这个cookie。Max-age相比Expires将优先生效。如果Set-cookie没有指定Expires或者Max-age,则这个cookie为sessioncookie,浏览器关闭后,cookie将自动被清除。

Secure/HttpOnly

Secure指定浏览器只保存Https请求设置的cookie,非https请求的cookie将被忽略。
HttpOnly属性限制js脚本获取cookie,主要是Document.cookie属性、XMLHttpRequest对象和Request Api都拿不到该属性,防止cookie被获取,只有在发起请求的时候会自动携带。

Session

客户端请求服务端,服务端会为这次请求开辟一块内存空间,这个对象便是Session对象。他弥补了HTTP的无状态特性,服务器可以利用Session存储客户端在同一个会话期间的一些操作记录

工作流程

1.浏览器发送账号密码,服务器接收后检查用户库并校验。
2.校验成功以后,将用户的登录状态存入Session库,并生成一个SessionId,通过cookie的形式返回给用户。
3.浏览器接收SessionId,存入本地cookie。
4.浏览器再次发送请求时,将SeesionId带上。
5.服务端根据SessionId检查Session库的登录状态。
6.校验通过,服务端返回数据。

缺点

  • 请求在经过负载均衡以后,如果服务端没有将Session同步,就会出现服务A的Session在服务器B中失效的情况

Token

服务器维护Session也需要成本,比如Session的存放、分布式的问题。
Token是Session的进一步优化

工作流程

1.用户登录,服务端校验账号密码,获取用户信息。
2.把用户信息,通过Token配置生成Token,再通过cookie 返回给浏览器。
3.此后浏览器请求接口通过cookie携带Token。
4.服务端收到请求时校验Token,进行正常的业务处理。

token的编码

  • 如果token存放的内容不涉及敏感信息,可以直接使用base64编码进行处理
    若token涉及敏感信息,则需要进行防篡改的处理,比如用
  • SHA-256安全散列算法
  • HMAC-SHA256 使用散列算法的同时结合一个加密秘钥,可以保证数据的完整性,同时可以用来做某个消息的身份验证。
  • RSA256非对称加密 公钥加密 私钥解密

JWT

JWT全称是JSON Web Token。顾名思义,token本质上还是一个token。token额外增加了cookie的数量,但是数据本身没有规范的格式,所以一个有规范格式的JWT就出现了。

数据结构

由三段字符串组成,中间用 (.)分隔。

  • header 头部
  • payloda 负载
  • signature 签名
    header.payloda.signature
header

JSON对象,描述JWT元数据
{ "alg":"HS256", "typ":"JWT" }
alg: 签名的算法 默认是HMAC-SHA256
typ:令牌类型,JWT令牌统一写成JWT

payload

JSON对象,用来存放实际需要传递的数据,JWT规定了7个可选的官方字段

  • iss:签发人
  • exp: 过期时间
  • sub:主题
  • aud:受众
  • nbf:生效时间
  • iat:签发时间
  • jti: 编号
    除了官方字段,可以在这部分定义私有字段,比如
    { "name":"mike", "gender":"male", }
    JWT默认不加密,任何人可以读取,所以敏感信息不要存在这里。
signature

对前面两个部分的签名,防止数据被篡改需要一个只有服务端才知道的秘钥,不能泄露给用户,然后使用header部分定义的签名算法,按照下面的公式生成签名
HMACSHA256(base64UrlEncode(header)+'.'+base64UrlEncode(payload),secret)
算出签名以后,将header、payload和signature三个部分用’.'拼接成一个字符串,返回给用户。

特点

  • 默认不加密,但是也可以加密。服务器生成token以后,可以用密钥再加密一次
  • 在JWT不加密的情况下,不能将敏感数据写入JWT
  • JWT不仅可以用作认证,也可以用作交换信息,减少查询数据库的次数
  • 缺点:因为服务器不保存session状态,所以无法在使用过程中使某个token作废,只能等token过期。
  • JWT本身包含认证信息,为了安全问题,有效期应该设置得尽可能短。
  • JWT存放的信息很大,比普通的sessionId大多了,有可能一个请求,请求头比请求体还大,使用JWT的开销比使用session的大很多
  • 一次性,无状态是JWT的特点,但也导致了JWT一旦生成,要想修改其中的内容,必须签发一个新的JWT。

SSO 单点登录(Single Sign On)

将登录系统单独抽离出来,是一种比较流行的企业业务整合的解决方案。在多个系统中,用户只需要登录一次就可以访问所有信任的应用系统而不用重复登录。而如果用户在某个应用系统中进行注销登录,则所有的应用系统都不能再直接访问保护资源。

SSO流程:

  1. 用户访问还没有登录的app1系统
  2. 跳转到SSO系统,用户在SSO系统也没有登录,则进入SSO系统的登录页面
  3. 用户输入帐号密码,SSO认证通过以后,将登录态写入SSO的session,浏览器中写入SSO域下的cookie
  4. SSO系统登录完以后会生成一个ST(Service Ticket),将ST作为参数传递回app1系统
  5. app1拿到ST以后,拿着ST向SSO系统校验
  6. SSO系统对ST进行校验,通过后app1将登录状态写入seesion并设置app1域下的cookie。
    至此,SSO登录就已经完成,以后我们访问app1系统,app都是登录的。接下来看app2的登录流程。
  7. 用户访问未登录的app2系统,系统跳转到SSO系统,
  8. SSO系统已登录,则携带ST返回app2系统
  9. app2系统发送请求到SSO校验ST有效性。
  10. SSO系统校验通过,app2登录,将登录状态写入session,并在app2域下写下cookie。

可见,app2是不用再走一遍登录流程,就是已经的登录了。

猜你喜欢

转载自blog.csdn.net/vipshop_fin_dev/article/details/120261102