请求中的token机制

 

where(场景)

  1、csrf的服务端token

# 首先生成真实的raw_token并存到session或cookie中
def real_csrf_token(session) # :doc:
  session[:_csrf_token] ||= SecureRandom.base64(AUTHENTICITY_TOKEN_LENGTH)
  Base64.strict_decode64(session[:_csrf_token])
end

# 看到raw_token 只是一个已知长度的随机字符串,然后再base64之后,存到session中
raw_token = real_csrf_token(session)

# 给客户端的,客户端构造给表单hidden或ajax的mask_token
def mask_token
  one_time_pad = SecureRandom.random_bytes(AUTHENTICITY_TOKEN_LENGTH)
  encrypted_csrf_token = xor_byte_strings(one_time_pad, raw_token) # xor计算
  masked_token = one_time_pad + encrypted_csrf_token
	Base64.strict_encode64(masked_token)
end

# mask_token在前端页面是可以看到的

# 如果进行对比校验?
# 将前端传过来的masked_token 进行unmask 得到一个 unmask_token 再和session中的session[:_csrf_token]进行比较,相等说明校验通过,unmask 的过程就是mask的逆向过程

def unmask_token(masked_token) # :doc:
  one_time_pad = masked_token[0...AUTHENTICITY_TOKEN_LENGTH]
  encrypted_csrf_token = masked_token[AUTHENTICITY_TOKEN_LENGTH..-1]
  xor_byte_strings(one_time_pad, encrypted_csrf_token)
end

unmask_token == session[:_csrf_token] ? Yes : No

诠释:
  • 在这一次session的生命周期中,session[:_csrf_token] 是固定的
  • 每次给前端的mask_token是不一样的,是因为每次的one_time_pad是不一样的
  • 但是,每次将mask_token unmask逆向之后得到的real_token应该是一样的,然后和session[:_csrf_token]比较即可

 

  如果攻击者要破解CSRF token,他需要能够在session这次生命周期内拿到session[:_csrf_token] 如果session[:_csrf_token]存在cookie中,攻击者需要破解cookie得到真实数据。(防止方案:可以设置cookie的httponly属性为true,这样cookie就只能通过服务器读取不能通过javascript读取)

 

  2、部分代替分布式session的能力:

    

 

  跨站点方案:

    

 

 

 

  JWTtoken结构:

     本身可以带 uid 信息、校验信息,解密后就可以获取。

  

 

    token 主要由三部分组成 :

      1. header:指定了签名算法 ;

      2. payload:可以指定用户 id,过期时间等非敏感数据 ;

      3. Signature: 签名。server 根据 header 知道它该用哪种签名算法,再用密钥根据此签名算法对 head + payload 生成签名。

 

    payload字段:Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段,供选用,如下:

      

 

      其实,还可以在这个部分定义私有字段 。JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。

 

    JWT 的最大缺点:

      由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就> 是说,一旦 JWT 签发了,在到期之前就会始终有效。

 

    合法性验证:

      server 收到浏览器传过来的 token 时,它会首先取出 token 中的 header + payload,根据密钥(服务端知道)生成签名,然后再与 token 中的签名比对,如果成功则说明签名是合法的,即 token 是合法的。

      后面就可以使用payload中的信息了。

 

    使用流程:

      

 

 

 

 

 

 

 
posted @ 2022-02-17 19:02  修心而结网  阅读(190)  评论(0编辑  收藏  举报