谈谈cookie-session和JWT认证机制

总结了网上相关的博客以及一些个人的理解,欢迎指出错误

为什么需要这些认证机制

众所周知,http协议是一个无状态的协议,每个请求之间是独立的,没有关系的。但是在日常的实际应用中并不能满足我们的需求,我们需要区分请求的用户,需要保存一些访问的状态,因此需要引入会话管理机制,帮助我们区分用户

cookie-session

cookie是什么

cookie,简而言之就是在客户端(浏览器等)保存一些用户操作的历史信息(包括登录信息),并在用户再次访问该站点时浏览器通过HTTP协议将本地cookie内容发送给服务器,从而完成验证,或继续上一步操作

session是什么

session,简而言之就是在服务器上保存用户操作的历史信息,在用户登录后,服务器存储用户会话的相关信息,并为客户端指定一个访问凭证,如果有客户端凭此凭证发出请求,则在服务端存储的信息中,取出用户相关登录信息,并且使用服务端返回的凭证常存储于cookie中,也可以改写URL,将id放在url中。这个访问凭证一般来说就是session_id

机制原理

session是存放在服务端的,而cookie是存储在客户端的用户登录成功的时候,生成session_id,以session_idkey,用户信息经过一系列的加密处理生成value,写入session,session信息可以写入文件、数据库或memcached等等。推荐写入memcached,提高访问的速度。然后把session_id写入cookie存放在客户端,每次请求的时候,都会携带cookie,需要用户信息的时候,根据cookie里面的session_id直接从文件或者数据库或者memcached里面取出session信息即可

存在问题

  • seesion:每次认证用户发起请求时,服务器需要去创建一个记录来存储信息。当越来越多的用户发请求时,内存的开销也会不断增加。
  • 可扩展性:在服务端的内存中使用seesion存储登录信息,伴随而来的是可扩展性问题。
  • CORS(跨域资源共享):当我们需要让数据跨多台移动设备上使用时,跨域资源的共享会是一个让人头疼的问题。在使用Ajax抓取另一个域的资源,就可以会出现禁止请求的情况。
  • CSRF(跨站请求伪造):用户在访问银行网站时,他们很容易受到跨站请求伪造的攻击,并且能够被利用其访问其他的网站。

JWT(JSON WEB TOKEN)

JWT是什么

JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且独立的方式,用于在各方之间作为JSON对象安全地传输信息。此信息可以通过数字签名进行验证和信任。JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名。

JWT 结构

What is the JSON Web Token structure?

json web token从名字就可以看出来,是json格式的。具体而言,其分为header, payload, signature三部分,因此它的格式为:xxxxx.yyyyy.zzzzz

  • header
    header通常由两部分组成:令牌的类型,即JWT,以及正在使用的签名算法,例如HMAC、SHA256或RSA。
    例如:
    1
    2
    3
    4
    {
    "alg": "HS256",
    "typ": "JWT"
    }
  • payload
    payload信息,主要是claims,用户的信息,发布者的信息等等。这样我们在需要的时候需要的时候在payload里面保存一些信息,这样可以不用查询数据库就可以获取
    例如:

    1
    2
    3
    4
    5
    {
    "sub": "1234567890",
    "name": "John Doe",
    "admin": true
    }
  • signature
    要创建签名部分,对header, payload编码,外加一个secret,做一个散列算法

    例如,如果要使用HMAC SHA256算法,将按以下方式创建签名:

    1
    2
    3
    4
    HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    secret)

    签名用于验证消息在此过程中未被更改,并且,在使用私钥签名的令牌的情况下,它还可以验证JWT的发件人是否是它所声称的人

机制原理

首先用户发出登录请求,服务端根据用户的登录请求进行匹配,如果匹配成功,将相关的信息放入payload中,利用上述算法,加上服务端的密钥生成token,这里需要注意的是secret_key很重要,如果这个泄露的话,客户端就可以随意篡改发送的额外信息,它是信息完整性的保证。生成token后服务端将其返回给客户端,客户端可以在下次请求时,将token一起交给服务端,一般来说我们可以将其放在Authorization首部中,这样也就可以避免跨域问题。接下来,服务端根据token进行信息解析,再根据用户信息作出相应的操作

优势与不足

  • 优点
    • 不需要储存在服务器的session中,更容易扩展服务器
    • 由于用户信息可以放入token中,所以可以少了一次数据库 / 缓存的查询操作,有更好的性能
    • 不需要预防CSRF的攻击
    • 解决多平台跨域问题
  • 不足
    • token一经泄露或者被盗取,将会暴露该用户

参考