• token详细介绍及实现登录


    token出现的背景

            以前,Web 基本上就是文档的浏览而已,每次请求都是一个新的HTTP协议, 就是请求加响应,尤其是我不用记住是谁刚刚发了HTTP请求

            随着交互式Web应用的兴起,像在线购物网站,需要登录的网站等等,面临一个问题,必须记住哪些人登录系统,也就是说我必须把每个人区分开,这就是一个不小的挑战,因为HTTP请求是无状态的,起初想出的办法就是给每一个人发一个唯一的sessionid(一个随机的字符串),下次大家再向我发起HTTP请求的时候,把这个sessionid带着, 这样我就能区分开谁是谁了

           每个人只需要保存自己的session id,而服务器要保存所有人的session id !这对服务器说是一个巨大的开销, 严重的限制了服务器扩展能力, 比如说我用两个机器组成了一个集群, 小F通过机器A登录了系统, 那session id会保存在机器A上, 假设小F的下一次请求被转发到机器B怎么办? 机器B可没有小F的 session id啊。

    那只好做session 的复制了, 把session id 在服务器之间搬来搬去, 快累死了

    于是有人就一直在思考, 我为什么要保存这可恶的session, 只让每个客户端去保存该多好?

            可是如果不保存这些session id , 怎么验证客户端发给我的session id 的确是我生成的呢? 如果不去验证,我们都不知道他们是不是合法登录的用户, 那些不怀好意的家伙们就可以伪造session id , 为所欲为了。

    关键点就是验证 !

            比如说, 小F已经登录了系统, 我给他发一个令牌(token), 里边包含了小F的 user id, 下一次小F 再次通过Http 请求访问我的时候, 把这个token 通过Http header 带过来

            不过这和session id没有本质区别啊, 任何人都可以可以伪造, 所以我得想点儿办法, 让别人伪造不了。

            那就对数据做一个签名吧, 比如说我用HMAC-SHA256 算法,加上一个只有我才知道的密钥, 对数据做一个签名, 把这个签名和数据一起作为token , 由于密钥别人不知道, 就无法伪造token了

            这个token服务器不保存,当小F把这个token 给我发过来的时候,我再用同样的HMAC-SHA256 算法和同样的密钥,对数据再计算一次签名, 和token 中的签名做个比较, 如果相同, 我就知道小F已经登录过了,并且可以直接取到小F的user id , 如果不相同, 数据部分肯定被人篡改过, 我就告诉发送者: 对不起,没有认证

            解除了session id这个负担, 可以说是无事一身轻, 我的机器集群现在可以轻松地做水平扩展, 用户访问量增大, 直接加机器就行。 这种无状态的感觉实在是太好了 

    JWT就是token的一种具体实现方式

    JWT本质就是一个字符串,将用户信息存储到一个JSON中,然后编码得到一个JWT token,这个token带有签名信息,服务器接收后可以校验是否被篡改

    一个JWT token格式如下所示

    他是由.分割的三部分组成,这三部分依次是:

    • 头部(Header):

      • alg是签名用的算法,默认为HMAC SHA256(写为HS256);

      • typ属性表示令牌的类型,JWT令牌统一写为JWT。

      • 最后,使用Base64 URL算法将上述JSON对象转换为字符串保存

        1. {
        2. "alg": "HS256",
        3. "typ": "JWT"
        4. }
    • 负载(Payload):是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 JWT指定七个默认字段供选择

        1. iss:发行人
        2. exp:到期时间
        3. sub:主题
        4. aud:用户
        5. nbf:在此之前不可用
        6. iat:发布时间
        7. jti:JWT ID用于标识该JWT
      • 除以上默认字段外,我们还可以自定义私有字段,一般会把包含用户信息的数据放到payload中,如下

        1. {
        2. "sub": "1234567890",
        3. "name": "Helen",
        4. "admin": true
        5. }
      • 请注意,默认情况下JWT是未加密的,因为只是采用base64算法,拿到JWT字符串后可以转换回原本的JSON数据,任何人都可以解读其内容,因此不要构建隐私信息字段,比如用户的密码一定不能保存到JWT中,以防止信息泄露。JWT只是适合在网络中传输一些非敏感的信息
    • 签名(Signature)

    • 签名哈希部分是对上面两部分数据签名,需要使用base64编码后的header和payload数据,通过指定的算法生成哈希,以确保数据不会被篡改。首先,需要指定一个密钥(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。然后,使用header中指定的签名算法(默认情况下为HMAC SHA256)根据以下公式生成签名
      
      
      在计算出签名哈希后,JWT头,有效载荷和签名哈希的三个部分组合成一个字符串,每个部分用.分隔,就构成整个JWT对象
    注意JWT每部分的作用,在服务端接收到客户端发送过来的JWT token之后:
    
        header和payload可以直接利用base64解码出原文,从header中获取哈希签名的算法,从payload中获取有效数据
        signature由于使用了不可逆的加密算法,无法解码出原文,它的作用是校验token有没有被篡改。服务端获取header中的加密算法之后,利用该算法加上secretKey对header、payload进行加密,比对加密后的数据和客户端发送过来的是否一致。注意secretKey只能保存在服务端,而且对于不同的加密算法其含义有所不同,一般对于MD5类型的摘要加密算法,secretKey实际上代表的是盐值

    头部和负载以json形式存在,这就是JWT中的JSON,三部分的内容都分别单独经过了Base64编码,以.拼接成一个JWT Token

    token登录过程

    • 首次登录输入账号密码,账号密码验证无误后,服务器会随机生成一个token值(令牌)
    • 将服务器返回的token值 在我们本地进行存储(服务器端不需要存储)
    • 下次登陆时就携带这个token(我们把token值放在http请求头 -> Authorization = "XXX")
    • 服务器进行验证token,如果有效则登录成功
    • 最后在退出登陆时,将token在本地化存储中删除

    token登录对比传统session认证方式的优点如下

    1、支持跨域访问:cookie是无法跨域的,而token由于没有用到cookie(前提是将token放到请求头中),所以跨域后不会存在信息丢失问题。

    2、无需考虑CSRF(跨站请求伪造):由于不再依赖cookie,所以采用token认证方式不会发生CSRF,所以也就无需考虑CSRF的防御

    3、更适用于移动端:当客户端是非浏览器平台时,cookie是不被支持的,此时采用token认证方式会简单很多

    4、减轻服务器的压力:token机制在服务端不需要存储session信息,因为token自身包含了所有登录用户的信息,所以可以减轻服务端压力。

    JWT(JSON Web Token)

    JWT就是上述流程当中token的一种具体实现方式,本质就是一个字符串,它是将用户信息保存到一个Json字符串中,然后进行Base64编码后得到一个JWT token。

    流程 : 首先用户输入账号密码后,在服务器进行验证,如果无误的话,在服务器生成通过base64编码生成一个JWT Token(字符串),服务器把这个字符串传给客户端进行本地化存储,退出时删除这个字符串就可以, 前端在每次请求时将JWT Token放入HTTP请求头中的Authorization属性中

  • 相关阅读:
    MySQL数据库——MySQL日志及分类
    实现声明式锁,支持分布式锁自定义锁、SpEL和结合事务
    【unity】制作一个角色的初始状态(左右跳二段跳)【2D横板动作游戏】
    【C++】手撕string(string的模拟实现)
    【BP回归预测】基于matlab文化算法优化BP神经网络数据回归预测【含Matlab源码 2124期】
    DS18B20驱动编写--杂项设备框架注册
    时空智友企业流程化管控系统文件存在任意文件上传漏洞 附POC
    前端页面初步开发
    PHP 字符串常用函数
    基于SPI机制手动模拟数据库驱动打成Jar包使用
  • 原文地址:https://blog.csdn.net/m0_56750901/article/details/125493359