Jwt

Jwt
1、服务端如何利用jwt生成token令牌
2、客户端如何接收jwt生成的令牌
3、与传统的session机制差异在哪

传统的session认证

http协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再一次进行用户认证才行,因为根据http协议,我们并不能知道是哪个用户发送的请求,所以为了让我们的应用能识别是哪个用户发出的,我们只能在服务器存储一份用户登陆的信息,这份登陆信息会在响应时传递给服务器,告诉其保存为cookie,以便下次请求时发送给我们的应用,这样我们的英哟个就能识别请求来自哪个用户了,这就是传统的基于sessino认证。

基于session认证所显露的问题

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

基于token的鉴权机制

基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或会话信息。这也就意味着机遇tokent认证机制的应用不需要去考虑用户在哪一台服务器登陆了,这就为应用的扩展提供了便利

流程是这样的
用户使用用户名密码请求服务器
服务器进行验证用户信息
服务器通过验证发送给用户一个token
客户端存储token,并在每次请求时附加这个token值
服务器验证token,并返回数据
这个token必须要在每次请求时发送给服务器,它应该保存在请求头中,另外,服务器要支持CORS(跨来源资源共享)策略,一般我们在服务端这么做就可以了 Access-Control-Allow-Origin:*
Jwt_第2张图片
1、 JWT是什么
Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于分布式站点的单点登陆(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

2.、为什么使用JWT
JWT的精髓在于:“去中心化”,数据是保存在客户端的。

3、 JWT的工作原理

  1. 是在服务器身份验证之后,将生成一个JSON对象并将其发送回用户,示例如下:
    {“UserName”: “Chongchong”,“Role”: “Admin”,“Expire”: “2018-08-08 20:15:56”}

  2. 之后,当用户与服务器通信时,客户在请求中发回JSON对象

  3. 为了防止用户篡改数据,服务器将在生成对象时添加签名,并对发回的数据进行验证

4.、JWT组成

一个JWT实际上就是一个字符串,它由三部分组成:头部(Header)、载荷(Payload)与签名(signature)
JWT结构原理图:见资料“JWT的数据结构.jpg”
Jwt_第3张图片
5. JWT的验证过程

它验证的方法其实很简单,只要把header做base64url解码,就能知道JWT用的什么算法做的签名,然后用这个算法,再次用同样的逻辑对header和payload做一次签名,

并比较这个签名是否与JWT本身包含的第三个部分的串是否完全相同,只要不同,就可以认为这个JWT是一个被篡改过的串,自然就属于验证失败了。

接收方生成签名的时候必须使用跟JWT发送方相同的密钥

注1:在验证一个JWT的时候,签名认证是每个实现库都会自动做的,但是payload的认证是由使用者来决定的。因为JWT里面可能会包含一个自定义claim,
所以它不会自动去验证这些claim,以jjwt-0.7.0.jar为例:
A 如果签名认证失败会抛出如下的异常:
io.jsonwebtoken.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.

  即签名错误,JWT的签名与本地计算机的签名不匹配

    B JWT过期异常
      io.jsonwebtoken.ExpiredJwtException: JWT expired at 2017-06-13T11:55:56Z. Current time: 2017-06-13T11:55:57Z, a difference of 1608 milliseconds.  Allowed

Jwt_第4张图片

注2:认证失败,返回401 Unauthorized响应

注3:认证服务作为一个Middleware HOOK 对请求进行拦截,首先在cookie中查找Token信息,如果没有找到,则在HTTP Authorization Head中查找

  1. JWT令牌刷新思路

6.1 登陆成功后,将生成的JWT令牌通过响应头返回给客户端

6.2 WEB APP项目每次请求后台数据时(将JWT令牌从请求头中带过来),

  验证通过,刷新JWT,并保存在响应头返回给客户端,有效时间30分钟

  JwtFilter

注1:修改CorsFilter添加允许的新的请求头“jwt”

注2:原来在默认的请求上, 浏览器只能访问以下默认的 响应头

   Cache-Control

   Content-Language

   Content-Type

   Expires

   Last-Modified

   Pragma

   如果想让浏览器能访问到其他的 响应头的话 需要在服务器上设置 Access-Control-Expose-Headers
   Access-Control-Expose-Headers : 'jwt'
   // CorsFilter 允许客户端,发一个新的请求头jwt
   resp.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With, Content-Type, Accept, jwt");

http.js
将jwt令牌塞到request Headers里面

// 请求拦截器
axios.interceptors.request.use(function(config) {
	// 将jwt令牌塞到request Headers里面
	var jwt = window.vm.$store.getters.getJwt;
	config.headers['jwt'] = jwt;
	return config;
}, function(error) {
	return Promise.reject(error);
});

// 将jwt令牌塞到response Headers里面

// 响应拦截器
axios.interceptors.response.use(function(response) {
	// 将jwt令牌塞到response Headers里面
	// debugger;
	var jwt = response.headers['jwt'];
	if(jwt){
		window.vm.$store.commit('setJwt',{jwt:jwt});
	}
	return response;
}, function(error) {
	return Promise.reject(error);
});

还要在state里面配置变量jwt

export default{
        resturantName:'飞歌餐馆',
		jwt:null
}

提供set,get方法getters.js

export default{
       getResturantName: (state) => {
         return state.resturantName;
       },
	   getJwt: (state) => {
	   return state.jwt;
	   }
}

mutations.js

export default {
	setResturantName: (state, payload) => {
		state.resturantName = payload.resturantName;
	},
	setJwt: (state, payload) => {
		state.jwt = payload.jwt;
	}
}

在mian.js里面实例Vue

/* eslint-disable no-new */
window.vm = new Vue({
	el: '#app',
	data(){
		return{
			Bus:new Vue({
				
			})
		}
	},
	router,
	store,
	components: {
		App
	},
	template: ''
})

未登陆,什么操作都来不了
Jwt_第5张图片
登陆后
Jwt_第6张图片
总结
优点:
因为json的通用性,所以JWT是可以跨语言支持的,像C#,JavaScript,NodeJS,PHP等许多语言都可以使用
因为由了payload部分,所以JWT可以在自身存储一些其它业务逻辑所必要的非敏感信息
便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的
它不需要在服务端保存会话信息,所以它易于应用的扩展
安全相关

不应该在jwt的payload部分存储敏感信息,因为该部分是客户端可解密的部分
保护好secret私钥。该私钥非常重要
如果可以,请使用https协议

你可能感兴趣的:(java)