SpringBoot2.0 整合 JWT 框架,解决Token跨域验证问题
程序员文章站
2022-03-20 17:56:22
一、传统Session认证 1、认证过程 2、存在问题 二、JWT简介 JWT(全称:JSON Web Token),在基于HTTP通信过程中,进行身份认证。 1、认证流程 2、JWT结构说明 抓一只鲜活的Token过来。 上面的Token被手动格式化了,实际上是用"."分隔的一个完整的长字符串。 ......
github源码地址:知了一笑 https://github.com/cicadasmile/middle-ware-parent
一、传统session认证
1、认证过程
1、用户向服务器发送用户名和密码。 2、服务器验证后在当前对话(session)保存相关数据。 3、服务器向返回sessionid,写入客户端 cookie。 4、客户端每次请求,需要通过 cookie,将 sessionid 回传服务器。 5、服务器收到 sessionid,验证客户端。
2、存在问题
1、session保存在服务端,客户端访问高并发时,服务端压力大。 2、扩展性差,服务器集群,就需要 session 数据共享。
二、jwt简介
jwt(全称:json web token),在基于http通信过程中,进行身份认证。
1、认证流程
1、客户端通过用户名和密码登录服务器; 2、服务端对客户端身份进行验证; 3、服务器认证以后,生成一个 json 对象,发回客户端; 4、客户端与服务端通信的时候,都要发回这个 json 对象; 5、服务端解析该json对象,获取用户身份; 6、服务端可以不必存储该json(token)对象,身份信息都可以解析出来。
2、jwt结构说明
抓一只鲜活的token过来。
{ "msg": "验证成功", "code": 200, "token": "eyj0exaioijkv1qilcjhbgcioijiuzuxmij9. eyjzdwiioijhzg1pbiisimlhdci6izeij3fq. uejsjagjf1j7a55wwr1bgsb5yqoayz5rbftf" }
上面的token被手动格式化了,实际上是用"."分隔的一个完整的长字符串。
jwt结构
1、头部(header) 声明类型以及加密算法; 2、负载(payload) 携带一些用户身份信息; 3、签名(signature) 签名信息。
3、jwt使用方式
通常推荐的做法是客户端在 http 请求的头信息authorization字段里面。
authorization: bearer <token>
服务端获取jwt方式
string token = request.getheader("token");
三、与springboot2整合
1、核心依赖文件
<dependency> <groupid>io.jsonwebtoken</groupid> <artifactid>jjwt</artifactid> <version>0.7.0</version> </dependency>
2、配置文件
server: port: 7009 spring: application: name: ware-jwt-token config: jwt: # 加密密钥 secret: iwqjhda8232bjgh432[cicada-smile] # token有效时长 expire: 3600 # header 名称 header: token
3、jwt配置代码块
@configurationproperties(prefix = "config.jwt") @component public class jwtconfig { /* * 根据身份id标识,生成token */ public string gettoken (string identityid){ date nowdate = new date(); //过期时间 date expiredate = new date(nowdate.gettime() + expire * 1000); return jwts.builder() .setheaderparam("typ", "jwt") .setsubject(identityid) .setissuedat(nowdate) .setexpiration(expiredate) .signwith(signaturealgorithm.hs512, secret) .compact(); } /* * 获取 token 中注册信息 */ public claims gettokenclaim (string token) { try { return jwts.parser().setsigningkey(secret).parseclaimsjws(token).getbody(); }catch (exception e){ e.printstacktrace(); return null; } } /* * token 是否过期验证 */ public boolean istokenexpired (date expirationtime) { return expirationtime.before(new date()); } private string secret; private long expire; private string header; // 省略 get 和 set }
四、token拦截案例
1、配置token拦截器
@component public class tokeninterceptor extends handlerinterceptoradapter { @resource private jwtconfig jwtconfig ; @override public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception { // 地址过滤 string uri = request.getrequesturi() ; if (uri.contains("/login")){ return true ; } // token 验证 string token = request.getheader(jwtconfig.getheader()); if(stringutils.isempty(token)){ token = request.getparameter(jwtconfig.getheader()); } if(stringutils.isempty(token)){ throw new exception(jwtconfig.getheader()+ "不能为空"); } claims claims = jwtconfig.gettokenclaim(token); if(claims == null || jwtconfig.istokenexpired(claims.getexpiration())){ throw new exception(jwtconfig.getheader() + "失效,请重新登录"); } //设置 identityid 用户身份id request.setattribute("identityid", claims.getsubject()); return true; } }
2、拦截器注册
@configuration public class webconfig implements webmvcconfigurer { @resource private tokeninterceptor tokeninterceptor ; public void addinterceptors(interceptorregistry registry) { registry.addinterceptor(tokeninterceptor).addpathpatterns("/**"); } }
3、测试接口代码
@restcontroller public class tokencontroller { @resource private jwtconfig jwtconfig ; // 拦截器直接放行,返回token @postmapping("/login") public map<string,string> login (@requestparam("username") string username, @requestparam("password") string password){ map<string,string> result = new hashmap<>() ; // 省略数据源校验 string token = jwtconfig.gettoken(username+password) ; if (!stringutils.isempty(token)) { result.put("token",token) ; } result.put("username",username) ; return result ; } // 需要 token 验证的接口 @postmapping("/info") public string info (){ return "info" ; } }
五、源代码地址
github地址:知了一笑 https://github.com/cicadasmile/middle-ware-parent 码云地址:知了一笑 https://gitee.com/cicadasmile/middle-ware-parent