Getway jwt 单点登录以及刷新token时间

不用nosql或其他
1.集成jwt
pom依赖:

 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.0</version></dependency>

2.jwt工具类

package com.zkhx.uitls;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.util.StringUtils;import javax.servlet.http.HttpServletRequest;
import java.util.Date;/*** @author kai* @since 2020*/
public class JwtUtils {//设置token过期时间
//    public static final long EXPIRE = 1000 * 60 * 60 * 24;public static final long EXPIRE = 2000 * 60;//加密秘钥,可以随便写public static final String KAI_SECRET = "xxxxxxxxxxxxx";//这个是生成token的方法,参数可多个public static String getJwtToken(String id, String nickname){String JwtToken = Jwts.builder()//这个是头信息.setHeaderParam("typ", "JWT").setHeaderParam("alg", "HS256")//这里是设置过期时间.setSubject("kj-user").setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + EXPIRE))//设置token的主体信息,存储用户信息.claim("id", id).claim("nickname", nickname)//.claim("xxx", xxx)//签发hash  根据KAI_SECRET秘钥  HS256方式生成.signWith(SignatureAlgorithm.HS256, KAI_SECRET).compact();return JwtToken;}/*** 判断token是否存在与有效* @param jwtToken* @return*/public static boolean checkToken(String jwtToken) {if(StringUtils.isEmpty(jwtToken)) return false;try {Jwts.parser().setSigningKey(KAI_SECRET).parseClaimsJws(jwtToken);} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** 判断token是否存在与有效* @param request* @return*/public static boolean checkToken(HttpServletRequest request) {try {String jwtToken = request.getHeader("token");if(StringUtils.isEmpty(jwtToken)) return false;Jwts.parser().setSigningKey(KAI_SECRET).parseClaimsJws(jwtToken);//根据秘钥解析,如果异常,则返回false} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** 根据token获取会员id* @param request* @return*/public static String getMemberIdByJwtToken(HttpServletRequest request) {String jwtToken = request.getHeader("token");if(StringUtils.isEmpty(jwtToken)) return "";Jws<Claims> claimsJws = Jwts.parser().setSigningKey(KAI_SECRET).parseClaimsJws(jwtToken);Claims claims = claimsJws.getBody();return (String)claims.get("id");}/*** 根据token获取nickname* @param request* @return*/public static String getNameByJwtToken(HttpServletRequest request) {String jwtToken = request.getHeader("token");if(StringUtils.isEmpty(jwtToken)) return "";Jws<Claims> claimsJws = Jwts.parser().setSigningKey(KAI_SECRET).parseClaimsJws(jwtToken);Claims claims = claimsJws.getBody();return (String)claims.get("nickname");}}

用户服务登录获取token

package com.zkhx.dept.controller;import com.github.pagehelper.PageInfo;
import com.zkhx.dept.service.UserService;
import com.zkhx.entity.UnitEntity;
import com.zkhx.entity.UserEntity;
import com.zkhx.uitls.JwtUtils;
import com.zkhx.uitls.MD5;
import com.zkhx.uitls.ResultCode;
import com.zkhx.uitls.ResultMsg;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;/*** @author qinKJ* @version 1.0* @date 2020.12.7 11:50*/
@RestController
@Slf4j
@RequestMapping("/xxx/xxx")
@Api(tags = "",description = "")
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/UserController/userLogin")public ResultMsg userLogin(@RequestParam("username") String username,@RequestParam("password") String password){try {UserEntity userEntity=new UserEntity();userEntity.setPassword(MD5.encrypt(password));userEntity.setUsername(username);UserEntity userEntity1 = userService.userLogin(userEntity);if(userEntity1!=null&&!userEntity1.equals("")){String jwtToken = JwtUtils.getJwtToken(String.valueOf(userEntity1.getId()), userEntity1.getUsername());return ResultMsg.successMsg().data(jwtToken);}else {return ResultMsg.failMsg(ResultCode.DATANULL,"登录失败,请检查用户名和密码是否正确");}}catch (Exception e){return ResultMsg.failMsg(ResultCode.ERROR,"发生异常");}}
}


getway服务
依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId><version>${boot-version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId><version>${boot-version}</version></dependency><!--jwt--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.0</version></dependency>

getway与web是有冲突的,servlet不能用,用 的ServerHttpRequest ServerHttpResponse
原jwt工具类是涉及到servlet的,复制改造jwt工具类到网关服务

package com.zkhx.utils;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.util.StringUtils;import java.util.Date;/*** @author qinKJ* @version 1.0* @date 2020.12.30 10:55*/
public class JwtUtil {public static final String KAI_SECRET = "xxxxx";//设置token过期时间//    public static final long EXPIRE = 1000 * 60 * 60 * 24;public static final long EXPIRE = 2000 * 60;//这个是生成token的方法,参数可多个public static String getJwtToken(String id, String nickname){String JwtToken = Jwts.builder()//这个是头信息.setHeaderParam("typ", "JWT").setHeaderParam("alg", "HS256")//这里是设置过期时间.setSubject("kj-user").setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + EXPIRE))//设置token的主体信息,存储用户信息.claim("id", id).claim("nickname", nickname)//.claim("xxx", xxx)//签发hash  根据KAI_SECRET秘钥  HS256方式生成.signWith(SignatureAlgorithm.HS256, KAI_SECRET).compact();return JwtToken;}/*** 判断token是否存在与有效* @param jwtToken* @return*/public static boolean checkToken(String jwtToken) {if(StringUtils.isEmpty(jwtToken)) return false;try {Jwts.parser().setSigningKey(KAI_SECRET).parseClaimsJws(jwtToken);} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** 根据token获取nickname* @param jwtToken* @return*/public static String getNameByJwtToken(String jwtToken) {if(StringUtils.isEmpty(jwtToken)) return "";Jws<Claims> claimsJws = Jwts.parser().setSigningKey(KAI_SECRET).parseClaimsJws(jwtToken);Claims claims = claimsJws.getBody();return (String)claims.get("nickname");}/*** 根据token获取会员id* @param jwtToken* @return*/public static String getMemberIdByJwtToken(String jwtToken) {if(StringUtils.isEmpty(jwtToken)) return "";Jws<Claims> claimsJws = Jwts.parser().setSigningKey(KAI_SECRET).parseClaimsJws(jwtToken);Claims claims = claimsJws.getBody();return (String)claims.get("id");}/*** 判断是可以刷新token,根据自己的业务来* @param token* @param lastPasswordReset* @return*/public static Boolean canTokenBeRefreshed(String token, Date xxx) {Claims claims;try {claims = Jwts.parser().setSigningKey(KAI_SECRET).parseClaimsJws(token).getBody();final Date iat = claims.getIssuedAt();final Date exp = claims.getExpiration();if (iat.before(xxx) || exp.before(new Date())) {return false;}return true;} catch (Exception e) {return false;}}/*** 刷新token* @param token* @param id* @param nickname* @return*/public static String refreshToken(String token,String id, String nickname) {String refreshedToken;try {final Claims claims = Jwts.parser().setSigningKey(KAI_SECRET).parseClaimsJws(token).getBody();refreshedToken = getJwtToken(id, nickname);} catch (Exception e) {refreshedToken = null;}return refreshedToken;}
}

网关拦截器

package com.zkhx.filter;import com.google.gson.JsonObject;
import com.zkhx.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;/*** @author qinKJ* @version 1.0* @date 2020.12.30 9:50*/
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {private AntPathMatcher antPathMatcher = new AntPathMatcher();@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();String path = request.getURI().getPath();ServerHttpResponse response = exchange.getResponse();//校验用户必须登录if(antPathMatcher.match("/phm/fault/**", path)) {List<String> tokenList = request.getHeaders().get("token");String tokenJwt=request.getHeaders().getFirst("token");if(null == tokenList) {
//                ServerHttpResponse response = exchange.getResponse();return out(response);} else if(JwtUtil.checkToken(tokenJwt)) {String nameByJwtToken = JwtUtil.getNameByJwtToken(tokenJwt);String memberIdByJwtToken = JwtUtil.getMemberIdByJwtToken(tokenJwt);
****************************************************************测试用****************************************************************Claims claims1 = Jwts.parser().setSigningKey("ukc8BDbRigUDaY6pZFfWus2jZWLPHO").parseClaimsJws(tokenJwt).getBody();Date d1 = claims1.getIssuedAt();Date d2 = claims1.getExpiration();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");System.out.println("username参数值:" + claims1.get("username"));System.out.println("登录用户的id:" + claims1.getId());System.out.println("登录用户的名称:" + claims1.getSubject());System.out.println("令牌签发时间:" + sdf.format(d1));System.out.println("令牌过期时间:" + sdf.format(d2));Boolean aBoolean = JwtUtil.canTokenBeRefreshed(tokenJwt, new Date());if (!aBoolean){tokenJwt=JwtUtil.refreshToken(tokenJwt,memberIdByJwtToken,nameByJwtToken);Claims claims2 = Jwts.parser().setSigningKey(JwtUtil.KAI_SECRET).parseClaimsJws(tokenJwt).getBody();Date d3 = claims2.getIssuedAt();Date d4 = claims2.getExpiration();System.out.println("username参数值:" + claims2.get("username"));System.out.println("登录用户的id:" + claims2.getId());System.out.println("登录用户的名称:" + claims2.getSubject());System.out.println("令牌签发时间:" + sdf.format(d3));System.out.println("令牌过期时间:" + sdf.format(d4));// 获取响应Header,目前的实现中返回的是HttpHeaders实例,可以直接修改response.getHeaders().add("new_token",tokenJwt);}
****************************************************************测试用****************************************************************// TODO 将token信息存放在请求header中传递给下游业务ServerHttpRequest.Builder mutate = request.mutate();mutate.header("AuthToken", tokenJwt);ServerHttpRequest buildReuqest = mutate.build();return chain.filter(exchange.mutate().request(buildReuqest).response(response).build());}else {
//                ServerHttpResponse response = exchange.getResponse();return out(response);}}//内部服务接口,不允许外部访问if(antPathMatcher.match("/**/knowledge/**", path)) {
//            ServerHttpResponse response = exchange.getResponse();return out(response);}return chain.filter(exchange);}@Overridepublic int getOrder() {return 0;}private Mono<Void> out(ServerHttpResponse response) {JsonObject message = new JsonObject();message.addProperty("success", false);message.addProperty("code", 28004);message.addProperty("data", "鉴权失败");byte[] bits = message.toString().getBytes(StandardCharsets.UTF_8);DataBuffer buffer = response.bufferFactory().wrap(bits);//response.setStatusCode(HttpStatus.UNAUTHORIZED);//指定编码,否则在浏览器中会中文乱码response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");return response.writeWith(Mono.just(buffer));}
}

接下来是给访问服务加过滤

package com.zkhx.config;/*** @author qinKJ* @version 1.0* @date 2020.12.30 14:13*/import com.zkhx.filter.TokenInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.ArrayList;
import java.util.List;/*** 拦截器配置*/
@Configuration
public class InterCepTerConfig implements WebMvcConfigurer {private TokenInterceptor tokenInterceptor;//构造方法public InterCepTerConfig(TokenInterceptor tokenInterceptor){this.tokenInterceptor = tokenInterceptor;}@Overridepublic void addInterceptors(InterceptorRegistry registry){List<String> excludePath = new ArrayList<>();
//        excludePath.add("/user_register"); //注册
//        excludePath.add("/login"); //登录
//        excludePath.add("/logout"); //登出
//        excludePath.add("/static/**");  //静态资源
//        excludePath.add("/swagger-ui.html/**");  //静态资源
//        excludePath.add("/assets/**");  //静态资源registry.addInterceptor(tokenInterceptor).addPathPatterns("/**").excludePathPatterns(excludePath);WebMvcConfigurer.super.addInterceptors(registry);}/*** 跨域支持** @param registry*/@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("*").allowCredentials(true).allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH", "OPTIONS", "HEAD").maxAge(3600 * 24);}}
package com.zkhx.filter;import com.alibaba.fastjson.JSONObject;
import com.zkhx.uitls.JwtUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;/*** @author qinKJ* @version 1.0* @date 2020.12.30 14:07* 防止直接访问*/
@Component
public class TokenInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception{if(request.getMethod().equals("OPTIONS")){response.setStatus(HttpServletResponse.SC_OK);return true;}response.setCharacterEncoding("utf-8");String token = request.getHeader("AuthToken");if(token != null){boolean result = JwtUtils.checkToken(token);if(result){return true;}}response.setCharacterEncoding("UTF-8");response.setContentType("application/json; charset=utf-8");PrintWriter out = null;try{JSONObject json = new JSONObject();json.put("success","false");json.put("msg","不能从这里访问哟");json.put("code","50000");response.getWriter().append(json.toJSONString());System.out.println("认证失败,未通过拦截器");//        response.getWriter().write("50000");}catch (Exception e){e.printStackTrace();response.sendError(500);return false;}return false;}
}

完毕,不通过网关访问接口:

登录服务获取到token,通过postman调试



替换token后再次访问

刷新成功

Getway jwt 单点登录以及刷新token时间相关推荐

  1. 登陆模块之JWT单点登录

    功能描述:通过一次登录来实现多个模块之间来回跳转,数据同步 单点登录的实现方式 redis实现session共享 jwt单点登录 cas单点登录 买单点登录服务器 本篇博客着重讲解JWT单点登录 首先 ...

  2. .net Core Jwt登录验证刷新Token

    使用 jwt做登录验证的时候,token的过期时间的固定的, 也就是只要经过了一定的时间肯定会过期.有可能用户用着系统就突然提示登录失效了.这里通过在行为结果过滤器Result Filter中刷新To ...

  3. jwt单点登录_单点登录SSO技术选型

    一些人存在的意义总归是让另一些人成长,然后消失. --刘同<谁的青春不迷茫> 1.单点登录是什么? 单点登录主要用于多系统集成,即在多个系统中,用户只需要到一个中央服务器登录一次即可访问这 ...

  4. jwt单点登录 和防重放攻击

    Json web token (JWT)(网络令牌), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的 ...

  5. 【Web技术】855- 八幅漫画理解 JWT单点登录设计

    本文地址:http://blog.leapoahead.com/2015/09/07/user-authentication-with-jwt/ 今天看到这篇用漫画描述 JWT,忍不住想分享,小伙伴们 ...

  6. cas jwt 单点登录

    单点登录是我比较喜欢的一个技术解决方案,一方面他能够提高产品使用的便利性,另一方面他分离了各个应用都需要的登录服务,对性能以及工作量都有好处.自从上次研究过JWT如何应用于会话管理,加之以前的项目中也 ...

  7. 单点登录SSO----JSON Web Token(JWT)机制

    JSON Web Token(JWT)机制 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns: ...

  8. 单点登录CAS的超时时间的设置

    http://www.mytju.com/classcode/news_readNews.asp?newsID=526 https://wiki.jasig.org/display/CASUM/HOW ...

  9. php token过期,前后端分离项目,token过期,重新登录和刷新token的问题

    这个我刚好在回答后端问题的时候做过详细的解释和方案说明 因为用的是我自己的框架,所以你看token部分的逻辑就好,不需要纠结具体的写法 主要就是checkTokenExpire 和 isTokenAl ...

最新文章

  1. python汉化之后好用吗_买了《Python学习手册(中文第4版)》后悔了
  2. Docker之几种storage-driver比较
  3. go语言buffio与继承
  4. URI结构和ABNF操作符
  5. 136 - Ugly Numbers
  6. lnmp 1.4 mysql_lnmp1.4配置https教程
  7. QT将绝对路径转成相对路径
  8. 全球最大语音识别公司Nuance的衰落与自我救赎
  9. 吸血鬼数字—THINKING IN JAVA中一道习题
  10. 60、在Visual Studio 2019 环境下,使用C#调用C++生成的dll实现yolov5的图片检测
  11. 模块化的ESP8266小电视设计与制作
  12. html 列表实现展开和收起,实现列表展开收起效果
  13. html5网页制作心得体会,学习网页制作心得体会范文3篇
  14. 透明网桥(计算机网络)
  15. 设计模式简介 - Introduction to Design Patterns
  16. 网页中漂浮的图片代码
  17. 在unik中,写一个Go HTTP服务器
  18. 基于51的双机通信系统
  19. 微信定向流量_我和我的小伙伴都玩微信定向流量了
  20. 大学计算机基础学生实验报告经验总结,安卓作业实验报告心得体会

热门文章

  1. Java八股整理--java基础
  2. Android程序的几个组成部分,Android应用程序开发的四个重要组成部分
  3. 牛客网 - 怪盗基德 月之瞳宝石
  4. Windows批处理中的if判断
  5. 【电脑主机的保养注意事项】
  6. 基于数据仓库的证券营业部客户细分分析
  7. linux 输出到终端
  8. 名编辑电子杂志大师教程 | 如何在电子宣传册中添加视频按钮?
  9. 2019迪拜电子展-Gitex2019
  10. [短视频运营] 抖音最新风口,漫改图文号,变现模式非常简单