Day20 JWT Token

What is JWT?

JWT全名为JSON Web Token,是一种跨域认证的Solution,它规定了一种Token的架构,并目前多用於前後分离场景与OAuth2.0的业务场景之下。

一般而言,使用者注册登入後会生成一个jwt token返回给浏览器,浏览器向服务端请求资料时携带 token ,服务器端使用 signature 中定义的方式进行解码,进而对token进行解析和验证。

JWT Token组成部分

https://mdimg.wxwenku.com/getimg/ccdf080c7af7e8a10e9b88444af98393328aa2998e4a67674f788858dc9a91c02199e40fdfd2cf3372e53609b9dc12ed.jpg

JWT-Toke的组成

  • Header: 用来指定使用的Algorithm(HMAC SHA256 RSA)和token type(如JWT),并透过Base64进行编码,范例如下
{
	"alg": "HS256",
	"typ": "JWT"
}
  • payload: 包含宣告(要求),宣告通常是使用者资讯或其他资料的宣告,比如User id, name, email等. 宣告可分为三种: registered, public, private,范例如下
{
  "_id": "<user_id>", 
  "name": "<user_name>",
  "email": "<user_email>"
}
  • signature: 用来保证JWT的真实性,可以使用不同的演算来加解密。为了得到signature部分,必须有编码过的header和payload,以及一个秘钥,签名演算法使用header中指定的那个,然後对其进行签名即可! 签名是 用於验证讯息在传递过程中有没有被更改 ,并且,对於使用私钥签名的token,它还可以验证JWT的传送方是否为它所称的传送方。

header

{
    "alg": "HS256",
    "typ": "JWT"
}

对上面的json进行base64编码即可得到JWT的第一个部分

payload

在 jwt.io 网站中,提供了一些JWT token的编码,验证以及生成jwt的工具。

下图就是一个典型的jwt-token的组成部分。

https://ithelp.ithome.com.tw/upload/images/20211005/20129737DxK27T4ixt.png

Why we need JWT?

在以往的web中,我们通常以Cookie-Session模式来实现用户登入,相关流程如下:

  1. 用户在浏览器填写帐号密码并发送给服务器端
  2. 服务端利用帐号密码验证,验证通过的话会生成一份保存当前用户讯息的Session data与相对应的Session id
  3. 服务器端在Response当中将Session Id返回并写入用户浏览器的Cookie当中
  4. 後续用户透过该浏览器的请求都会自动携带包含Session Id的Cookie
  5. 服务器端通过Request中的Session Id则可以找到之前保留的该用户数据,从而获取资讯。

但上述方式过於仰赖浏览器来保存Cookie,并且还需要额外在Server Side储存User Session Data。

在现今的互联网时代,有许许多多的Request来自非浏览器端,像是APP等,我们现今的前後端也慢慢地以分离式为主流并部署在不同的Port,甚至有时候还需要支援第三方登入,此时Cookie-Session方式就有点力不从心了。

https://ithelp.ithome.com.tw/upload/images/20211005/20129737aW6KstDck2.png

而JWT就是种基於Token的轻量级认证模式,Server Side通过认证後会生成一个JSON Object,并经过Signature得到一个Token再发回给User,此後User只要带上此Token,Server Side就能解密得到该User资讯。相关流程如下

  1. 用户在浏览器填写帐号密码并发送给服务器端
  2. 服务器端生成JWT Token,并返回给用户
  3. 用户在之後的Request都在Authorization header中,用Bearer schema带上Token Authorization: Bearer <token>
  4. 服务器端会进行Token验证
  5. 验证成功则开始执行该API所应该做的事,并返回正确的Response

https://ithelp.ithome.com.tw/upload/images/20211005/201297373qPHlgEs71.png

Token vs Cookie vs Session

Cookie

Cookie总是储存在客户端中,按在客户端的储存位置,可分为记忆体Cookie硬碟Cookie记忆体Cookie由浏览器维护,储存在记忆体中,浏览器关闭後就消失了,其存在时间是短暂的。硬碟Cookie储存在硬盘里,有一个过期时间,除非使用者手工清理或到了过期时间,硬碟Cookie不会被删除,其存在时间是长期的。所以,按存在时间,可分为 非持久Cookie和持久Cookie 。Cookie 是一个非常具体的东西,指的就是浏览器里面能永久储存的一种资料,仅仅是浏览器实现的一种资料储存功能。

一言堂: Cookie是储存在使用者浏览器端的资料,一般不超过4KB,主要记忆使用者的部分讯息,以此实现Session。

Session

Session字面意思是会话,主要用来标识自己的身份。比如在无状态的api服务在多次请求资料库时,如何知道是同一个使用者,这个就可以通过session的机制,服务器要知道当前发请求给自己的是谁

为了区分客户端请求, 服务端会给具体的客户端生成身份标识session ,然後客户端每次向服务器发请求的时候,都带上这个“身份标识”,服务器就知道这个请求来自於谁了。

至於客户端如何储存该标识,可以有很多方式,对於浏览器而言,一般都是使用 cookie 的方式

服务器使用session把使用者资讯临时储存了服务器上,使用者离开网站就会销毁,这种凭证储存方式相对於cookie来说更加安全,但是session会有一个缺陷: 如果web服务器做了负载均衡,那麽下一个操作请求到了另一台服务器的时候session会丢失。

因此,通常企业里会使用 redis,memcached 快取中介软件来实现session的共享,此时web服务器就是一个完全无状态的存在,所有的使用者凭证可以通过共享session的方式存取,当前session的过期和销毁机制需要使用者做控制。

一言堂: Session即为储存在服务器端有时效性的资料,通常要透过Cookie来找到该User的Session。

Token

Token的意思是"令牌",是使用者身份的验证方式,最简单的token组成: Uid(使用者唯一标识) + Time(当前时间戳) + Sign(签名,由token的前几位加上以杂凑演算法压缩成一定长度的十六进位制字串) ,同时还将不变的引数也放进Token。

一言堂: Token是一种在服务端不需要储存用户资料的身份验证方式,有透过加密且无状态并能接受所有域的请求。

Summary

这章节主要介绍JWT,让大家知道JWT的结构、功能以及在Web使用JWT的认证流程,而在下章节会配合以前的Code去搭建JWT的Auth API,并加入JWT认证机制到现有的API之中。

Reference

https://kknews.cc/zh-tw/code/6653eqp.html


<<:  Day-23 CPU Scheduling Algorithm

>>:  Day 20 架设开源的 CodiMD 服务

Day-06 Classification

昨天聊完如果要做资料 Regression(预测)的话,要给予基本的 Model + Data,并...

RISC-V on Rust 从零开始(1) - 安装 Rust 环境

工作之余兴起开发side project的念头,几经思考後决定以Rust语言撰写一个基本的RISC-...

[Tableau Public] day 10:试试长条图&地图,抓不到地图资讯怎麽办?

第10天,打完疫苗已经48小时,目前只有接种处抬手不会酸痛,昨天短暂晕完几分钟,就没感受到其他副作用...

Day 23 - 字串又来了,我还是没吃到串烧

Outline 可以把这三个东西理解成 class 的更多运用。 C++ Strings : 比之前...

Day17:关於 WS 的使用

前言 这两天因为卡文,所以笔记的部分变得很凌乱和断续,所以之後会再将前面的系列笔记重新调整成第二版,...