• JWT的优点、构成及搭建


    JWT

    		Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一
    		种基于 JSON 的开放标准((RFC 7519).定义了一种简洁的,自包含的方法用于
    		通信双方之间以 JSON 对象的形式安全的传递信息。因为数字签名的存在,这些
    		信息是可信的,JWT 可以使用 HMAC 算法或者是 RSA 的公私秘钥对进行签名
    
    • 1
    • 2
    • 3
    • 4

    传统session认证

    		   为了让我们的应用能识别是哪个用户发出的请求,我们只能在服
    		务器存储一份用户登录的信息,这份登录信息会在响应时传递给浏览器,告诉其
    		保存为 cookie,以便下次请求时发送给我们的应用,这样我们的应用就能识别请
    		求来自哪个用户了,这就是传统的基于 session 认证。
    		
    		  但是这种基于 session 的认证使应用本身很难得到扩展,随着不同客户端用
    		户的增加,独立的服务器已无法承载更多的用户,而这时候基于 session 认证应
    		用的问题就会暴露出来.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    传统session认证的问题

    		Session: 每个用户经过我们的应用认证之后,我们的应用都要在服务端做
    		一次记录,以方便用户下次请求的鉴别,通常而言 session 都是保存在内存中,
    		而随着认证用户的增多,服务端的开销会明显增大。
    		
    		扩展性: 用户认证之后,服务端做认证记录,如果认证的记录被保存在内存
    		中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授
    		权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味
    		着限制了应用的扩展能力。
    		
    		CSRF (跨站请求伪造):因为是基于 cookie 来进行用户识别的, cookie 如果
    		被截获,用户就会很容易受到跨站请求伪造的攻击。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    基于token的权限机制

    		基于 token 的鉴权机制类似于 http 协议也是无状态的,它不需要在服务端
    		去保留用户的认证信息或者会话信息。这就意味着基于 token 认证机制的应用
    		不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利
    
    • 1
    • 2
    • 3
    • 流程上是这样的:
    • 用户使用账号和密码发出 post 请求;
    • 服务器使用私钥创建一个 jwt;
    • 服务器返回这个 jwt 给浏览器;
    • 浏览器将该 jwt 串在请求头中像服务器发送请求;
    • 服务器验证该 jwt;
    • 返回响应的资源给浏览器。

    JWT的应用场景

    		   身份认证在这种场景下,一旦用户完成了登陆,在接下来的每个请求中包含
    		JWT,可以用来验证用户身份以及对路由,服务和资源的访问权限进行验证。由
    		于它的开销非常小,可以轻松的在不同域名的系统中传递,所有目前在单点登录
    		中比较广泛的使用了该技术。信息交换在通信的双方之间使用 JWT 对数据进行
    		编码是一种非常安全的方式,由于它的信息是经过签名的,可以确保发送者发送
    		的信息是没有经过伪造的。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    JWT的优点

    • 1.简洁(Compact): 可以通过 URL,POST 参数或者在 HTTP header 发送,因为数据量小,传输速度也很快
    • 2.自包含(Self-contained):负载中包含了所有用户所需要的信息,避免了多次查询数据库
    • 3.因为 Token 是以 JSON 加密的形式保存在客户端的,所以 JWT 是跨语言的,原则上任何 web 形式都支持。
    • 4.不需要在服务端保存会话信息,特别适用于分布式微服务。

    JWT的构成

    • JWT 是由三段信息构成的,将这三段信息文本用.链接一起就构成了 Jwt 字符串。
    • 第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 用户的信息),第三部分是签证(signature).

    举例

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiw
    ibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab3
    0RMHrHDcEfxjoYZgeFONFh7HgQ

    第一部分(header)

    	header
    	jwt 的头部承载两部分信息:
    		声明类型,这里是 jwt
    		声明加密的算法 通常直接使用 HMAC HS256
    	完整的头部就像下面这样的 JSON:
    	{
    	 	'typ': 'JWT',
    	 	 'alg': 'HS256' }
    	然后将头部进行 base64 转码,构成了第一部分.
    	 eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    第二部分(playload)

    	playload
    	载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效
    	信息包含三个部分
    		标准中注册的声明
    		公共的声明
    		公共的声明可以添加任何的信息,一般添加用户的相关信息或其
    		他业务 需要的必要信息.但不建议添加敏感信息(例如密码),因
    		为该部分在客户端可解密. id,用户名,头像名
    		私有的声明
    		定义一个 payload
    		{ "sub": "1234567890",
    			"name": "John Doe", "admin": true
    		}
    	然后将其进行 base64 转码,得到 Jwt 的第二部分。
    	eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4i
    	OnRydWV9
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    第三部分(signature)

    	signature
    	jwt 的第三部分是一个签证信息,这个签证信息由三部分组成:
    		header (base64 后的)
    		payload (base64 后的)
    		fsecret
    	这个部分需要 base64 转码后的 header 和 base64 转码后的 payload 使用.连
    	接组成的字符串,然后通过 header 中声明的加密方式进行加盐 secret 组合加密,
    	然后就构成了 jwt 的第三部分。
    	TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    JWT搭建

    引入 JWT 依赖,由于是基于 Java,所以需要的是 java-jwt

    	
    		com.auth0
    		java-jwt
    		3.8.2
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5

    创建生成token的方法

    /**
    * jwt 生成 token
    * @param id
    * @param account * @return
    */
    public static String token (Integer id, String account){
    	String token = "";
    	try {
    		//过期时间 为 1970.1.1 0:0:0 至 过期时间 当前的毫秒值 + 有效时间
    		Date expireDate = new Date(new Date().getTime() + 10*1000);
    		//秘钥及加密算法
    		Algorithm algorithm = Algorithm.HMAC256("随便一串安全密钥");
    		//设置头部信息
    		Map<String,Object> header = new HashMap<>();
    		header.put("typ","JWT");
    		header.put("alg","HS256");
    		//携带 id,账号信息,生成签名
    		token = JWT.create()
    					.withHeader(header)
    					.withClaim("id",id)
    					.withClaim("account",account)
    					.withExpiresAt(expireDate)
    					.sign(algorithm);
    	}catch (Exception e){
    		e.printStackTrace(); 
    		return null;
    	}return token;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    验证token是否有效

    public static boolean verify(String token){
    	try {
    		//验签
    		Algorithm algorithm = Algorithm.HMAC256("随便一串安全密钥");
    		JWTVerifier verifier = JWT.require(algorithm).build();
    		DecodedJWT jwt = verifier.verify(token); return true;
    	} catch (Exception e) {//当传过来的 token 如果有问题,抛出异常
    		return false;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    获得 token 中 playload 部分数据

    /**
     * 获得 token 中 playload 部分数据,按需使用
     * @param token
     * @return
    */
    public static DecodedJWT getTokenInfo(String token){
    	return JWT.require(Algorithm.HMAC256("随便一串安全密钥")).build().verify(token);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 用户登录成功后将用户 id 和账号存储到 token 中返回给客户端,之后客户端每次 请求将 token 发送到服务器端验证,
      在服务器中进行验证.
  • 相关阅读:
    javaWeb使用spring框架时在配置上的编程技巧
    halcon 圆点标定板相关算法说明及使用方法
    哈工大李治军老师操作系统笔记【3】:操作系统的接口(Learning OS Concepts By Coding Them !)
    【Linux】ping命令详解
    线性代数的艺术
    JavaScript快速入门
    Go面试题——log.fatal和panic的区别
    第一型曲面积分的第二型曲面积分的区别与联系【从几何知识的角度思考】
    复杂算子onnx导出(1): trace的实现
    Python3常用其他API速查手册(持续更新ing...)
  • 原文地址:https://blog.csdn.net/weixin_56781779/article/details/126271870