网站负责人信息表,asp网站做搜索,大丰建站,泗洪住房和城乡建设网站目录
一、JWT
1、什么是Jwt
2、为什么要使用Jwt
3、应用场景
4.Jwt的组成
4.1、Header
4.2、Payload
4.3、signature
二、Jwt验证过程
1、生成Jwt令牌
2、解析旧的Jwt 3、复制Jwt 4、Jwt有效时间测试 三、Jwt令牌刷新思路
1、配置JwtFilter过滤器
2、登录生成Jwt令…
目录
一、JWT
1、什么是Jwt
2、为什么要使用Jwt
3、应用场景
4.Jwt的组成
4.1、Header
4.2、Payload
4.3、signature
二、Jwt验证过程
1、生成Jwt令牌
2、解析旧的Jwt 3、复制Jwt 4、Jwt有效时间测试 三、Jwt令牌刷新思路
1、配置JwtFilter过滤器
2、登录生成Jwt令牌
3、配置CorsFilter过滤器 4、Vuex存储Jwt令牌
5、修改main.js
6、配置axios请求响应头 前言 随着前后端分离的发展以及数据中心的建立越来越多的公司会创建一个中心服务器服务于各种产品线。而这些产品线上的产品它们可能有着各种终端设备包括但不仅限于浏览器、桌面应用、移动端应用、平板应用、甚至智能家居。
这些设备与中心服务器之间会进行http通信一般来说中心服务器至少承担着认证和授权的功能。例如登录各种设备发送消息到中心服务器然后中心服务器响应一个身份令牌当这种结构出现后就出现一个问题它们之间还能使用传统的cookie方式传递令牌信息吗
其实也是可以的因为cookie在传输中无非是一个消息头而已只不过浏览器对这个消息头有特殊处理罢了。但浏览器之外的设备肯定不喜欢cookie因为浏览器有着对cookie完善的管理机制但是在其他设备上就需要开发者自己手动处理了。 JWT 的出现就是为了解决这个问题 一、JWT
1、什么是Jwt
JSON Web Token (JWT)是一个开放标准RFC 7519它定义了一种紧凑的、自包含的方式用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任因为它是数字签名的。是目前最流行的跨域身份验证解决方案 RFC 7519RFC 7519 - JSON Web Token (JWT) 2、为什么要使用Jwt
它要解决的问题就是为多种终端设备提供统一的、安全的令牌格式。因此jwt只是一个令牌格式而已你可以把它存储到cookie也可以存储到localstorage没有任何限制同样的对于传输你可以使用任何传输方式来传输jwt一般来说我们会使用消息头header来传输它。
比如当登录成功后服务器可以给客户端响应一个Jwt。
HTTP/1.1 200 OK
...
set-cookie:tokenjwt令牌
authorization:jwt令牌
...{..., token:jwt令牌} 可以看到jwt令牌可以出现在响应的任何一个地方客户端和服务器自行约定即可。 当然它也可以出现在响应的多个地方比如为了充分利用浏览器的 cookie同时为了照顾其他设备也可以让 jwt 出现在 set-cookie 和 authorization 或 body 中尽管这会增加额外的传输量。 总之Jwt的精髓在于去中心化数据是保存在客户端的。
3、应用场景
认证认证是JWT的最常用场景。只要用户完成登录其随后的请求都会包含JWT以允许用户访问经由当前JWT授权的路由、服务或者是资源。由于开销小且能够被简单应用在跨域访问上JWT在分布式站点上所支持的单点登录SSO已经是当前它被广泛应用的一个特性。信息交换JWT是一种在各参与方之间安全传递信息的良好方法。由于JWT可以被签名例使用公钥/秘钥对因而可用于确认发送者自称的身份。除此之外由于signature使用header和payload进行计算也可以验证内容没有被篡改。 JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息以便于从资源服务器获取资源也可以增加一些额外的其它业务逻辑所必须的声明信息该token也可直接被用于认证也可被加密。 4.Jwt的组成 一个Jwt实际上就是一个字符串它由三部分组成 Header头部 Payload载荷 Signature签名
eyJhbGciOiJIUzI1NiJ9.
eyJzdWIiOiJ7fSIsImlzcyI6InpraW5nIiwiZXhwIjoxNTYyODUwMjM3LCJpYXQiOjE1NjI4NDg0MzcsImp0aSI6ImM5OWEyMzRmMDc4NzQyZWE4YjlmYThlYmYzY2VhNjBlIiwidXNlcm5hbWUiOiJ6c3MifQ.
WUfqhFTeGzUZCpCfz5eeEpBXBZ8-lYg1htp-t7wD3I4 它是一个很长的字符串因此中间用点.分隔成三个部分。 注意Jwt 内部是没有换行的这里只是为了便于展示将它写成了几行。 4.1、Header
典型的JWT header包含两个部分 typtype属性用来标识整个token字符串是一个JWT字符串即JWT。 algalgorithm属性用来说明这个JWT签发的时候所使用的签名和摘要算法比如HMAC SHA256或者RSA。
{alg: HS256,typ: JWT
}
4.2、Payload
JWT token的第二部分是包含了声明的payload声明要求是一个实体的表述加上额外信息一共有三种形式的声明注册、公有和私有
注册声明
它的json结构实际上是对JWT要传递的数据的一组声明这些声明被JWT标准称为claims它的一个属性值对其实就是一个claim(要求)每一个claim的都代表特定的含义和作用。
{iss发行者,iat发布时间,exp到期时间,sub主题,aud听众,nbf在此之前不可用,jtiJWT ID
}
属性说明iss(Issuser)代表这个JWT的签发主体sub(Subject)代表这个JWT的主体即它的所有人aud(Audience)代表这个JWT的接收对象exp(Expiration time)是一个时间戳代表这个JWT的过期时间nbf(Not Before)是一个时间戳代表这个JWT生效的开始时间意味着在这个时间之前验证JWT是会失败的iat(Issued at)是一个时间戳代表这个JWT的签发时间jti(JWT ID)是JWT的唯一标识
公有声明
公有声明可以加入任何信息一般会添加用户相关信息或者业务需要的信息但不建议添加敏感信息因为该部分会在客户端解密。
私有声明
私有声明是提供者和使用者所共同定义的声明一般不建议存放敏感信息因为base64是对称解密基本等同于明文信息。 如果把JWT用于认证 那么JWT标准内规定的几个claim就足够用了甚至只需要其中一两个就可以了假如想往JWT里多存一些用户业务信息比如角色和用户名等这倒是可以用私有声明来添加。 4.3、signature
JWT的第三部分是签名信息Signature由三部分组成 headerbase64加密后 payloadbase64加密后 secret 盐
签名需要将base64加密后的header和payload使用.连接然后通过header所使用的加密方式进行加盐secret组合加密产生了jwt的第三部分。以使用HMAC SHA256算法为例 按照前面alg可用值的说明HS256其实包含的是两种算法:HMAC算法和SHA256算法前者用于生成摘要后者用于对摘要进行数字签名。这两个算法也可以用HMAC SHA256来统称; HMACSHA256(base64UrlEncode(header) . base64UrlEncode(payload),secret)
签名是用于验证消息在传递过程中有没有被更改并且对于使用私钥签名的token它还可以验证JWT的发送方是否为它所称的发送方。 算法不同签名结果不同。 二、Jwt验证过程 可将绑定的资源中src(ElementUI之Jwt)目录下的JwtUtils.java和JwtDemo.java导入到项目中的util包下
1、生成Jwt令牌
//定义私有声明
MapString, Object claims new HashMapString, Object();
claims.put(username, zss);
claims.put(age, 18);
//根据私有声明和JWT的token有效时间生成JWT
String jwt JwtUtils.createJwt(claims, JwtUtils.JWT_WEB_TTL);//获取JWT中的声明信息包括私有声明和标准声明
Claims parseJwt JwtUtils.parseJwt(jwt);
for (Map.EntryString, Object entry : parseJwt.entrySet()) {System.out.println(entry.getKey() entry.getValue());
}
//获取token令牌的签发时间
Date d1 parseJwt.getIssuedAt();
//获取token令牌的过期时间
Date d2 parseJwt.getExpiration();
System.out.println(令牌签发时间 sdf.format(d1));
System.out.println(令牌过期时间 sdf.format(d2));
2、解析旧的Jwt 解析旧的JWT。如果超过JWT本身定义的过期时间则直接抛出ExpiredJwtException
//旧的JWT令牌
String oldJwt eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjM2NzY0NDQsImlhdCI6MTU2MzY3NDY0NCwiYWdlIjoxOCwianRpIjoiMzE5MmYxOTg4NzFkNGVkZWIyMzU0MmY3NWVhMWI5NDciLCJ1c2VybmFtZSI6InpzcyJ92.4VnkdvGNNe8U1EiKaLz7h6bOJkVGSGtfqojcP_y-0Cc;
Claims parseJwt JwtUtils.parseJwt(oldJwt);
for (Map.EntryString, Object entry : parseJwt.entrySet()) {System.out.println(entry.getKey() entry.getValue());
}
Date d1 parseJwt.getIssuedAt();
Date d2 parseJwt.getExpiration();
System.out.println(令牌签发时间 sdf.format(d1));
System.out.println(令牌过期时间 sdf.format(d2)); 3、复制Jwt
模拟Session功能Tomcat默认session过期时间30分钟。当有访问的情况下自动延长jwt中的token令牌过期时间在原有时间上30秒
String oldJwt eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjM2NzUzMDAsImlhdCI6MTU2MzY3MzUwMCwiYWdlIjoxOCwianRpIjoiYjY5MmE5ZjZkMGZhNDMyN2I1YWY2NTI5OGMzMjQ5MTYiLCJ1c2VybmFtZSI6InpzcyJ9.asHGMPFKURMLnooK29abAuKEdLOHBycAuTovNuGQio0;
String jwt JwtUtils.copyJwt(oldJwt, JwtUtils.JWT_WEB_TTL);
Claims parseJwt JwtUtils.parseJwt(jwt);
for (Map.EntryString, Object entry : parseJwt.entrySet()) {System.out.println(entry.getKey() entry.getValue());
}
Date d1 parseJwt.getIssuedAt();
Date d2 parseJwt.getExpiration();
System.out.println(令牌签发时间 sdf.format(d1));
System.out.println(令牌过期时间 sdf.format(d2)); 4、Jwt有效时间测试
生成新的Jwt令牌设置令牌有效时间3秒钟在3秒钟后再次解析Jwt令牌提示令牌已过期。
MapString, Object claims new HashMapString, Object();
claims.put(username, zss);
String jwt JwtUtils.createJwt(claims, 3 * 1000L);
System.out.println(jwt);
Claims parseJwt JwtUtils.parseJwt(jwt);
Date d1 parseJwt.getIssuedAt();
Date d2 parseJwt.getExpiration();
System.out.println(令牌签发时间 sdf.format(d1));
System.out.println(令牌过期时间 sdf.format(d2)); 三、Jwt令牌刷新思路 使用ssmvueelementui实现jwt验证。
1、配置JwtFilter过滤器
导入JwtFilter.java到utils包下并注意配置顺序问题CorsFilter JwtFilter SpringMVC核心控制器
!-- JwtFilter --
filterfilter-namejwtFilter/filter-namefilter-classcom.wsl.ssm.jwt.JwtFilter/filter-class
/filter
filter-mappingfilter-namejwtFilter/filter-nameurl-pattern/*/url-pattern
/filter-mapping
2、登录生成Jwt令牌
在登录成功后使用JwtUtil工具类生成JWT并将Jwt令牌添加到响应头response中带到前端页面。在这里可以将用户对应用户基本信息和用户角色信息保存到私有claim中。
if(userVo.getUsername().equals(admin)userVo.getPassword().equals(123)){//私有要求claimMapString,Object jsonnew HashMapString,Object();json.put(username, userVo.getUsername());//生成JWT并设置到response响应头中String jwtJwtUtils.createJwt(json, JwtUtils.JWT_WEB_TTL);response.setHeader(JwtUtils.JWT_HEADER_KEY, jwt);return new JsonResponseBody(用户登陆成功,true,0,null);
}else{return new JsonResponseBody(用户名或密码错误,false,0,null);
}
3、配置CorsFilter过滤器
浏览器只能访问默认的响应头例如Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma等如果想让浏览器能访问到其他的响应头的话需要在服务器上设置。在CorsFilter跨域过滤器的doFilter方法中配置其他响应头的支持。
//允许客户端发一个新的请求头jwt
httpResponse.setHeader(Access-Control-Allow-Headers,Origin,X-Requested-With, Content-Type, Accept, jwt);
//允许客户端处理一个新的响应头jwt
httpResponse.setHeader(Access-Control-Expose-Headers, jwt); 4、Vuex存储Jwt令牌
使用vuex保存后端服务器提交过来的Jwt分别在state、getters、mutation中定义信息。
state.js export default {jwt:null
} getters.js export default {getJwt:(state){return state.jwt;}
} mutation.js export default {setJwt:function (state, payload){state.jwt payload.jwt;}
}
5、修改main.js
解决axios从响应头获得jwt令牌并保存到vuex通过修改main.js中的配置window.vmnew Vue({});获取Vue根实例对象。
window.vm new Vue({el: #app,router,store,components: { App },template: App/
})
6、配置axios请求响应头
在vue的http.js中配置axios的请求响应拦截器用于存取Jwt并将Jwt信息保存到Vuex中。
// 请求拦截器
axios.interceptors.request.use(function(config) {let jwtwindow.vm.$store.getters.jwt;//console.log(jwt);if(jwt)config.headers[jwt]jwt;return config;
}, function(error) {return Promise.reject(error);
});// 响应拦截器
axios.interceptors.response.use(function(response) {let jwtresponse.headers[jwt];if(jwt)window.vm.$store.commit(setJwt,{jwt:jwt});return response;
}, function(error) {return Promise.reject(error);
});
注可通过使用vuex-along解决刷新state初始化问题。