免费爱碰视频在线观看,九九精品国产屋,欧美亚洲尤物久久精品,1024在线观看视频亚洲

      SpringCloud Gateway API接口安全設計(加密 、簽名、安全)

      SpringCloud Gateway API接口安全設計(加密 、簽名、安全)

      防止數據抓包竊取

      風險簡述

      簡述:當用戶登錄時,惡意攻擊者可以用抓包工具可以拿到用戶提交的表單信息,可以獲取用戶的賬號密碼,進而可以惡意訪問網站。

      RSA 非對稱加密

      RSA簡介

      RSA加密算法是一種非對稱加密算法。在公開密鑰加密和電子商業(yè)中RSA被廣泛使用。RSA是1977年由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的。當時他們三人都在麻省理工學院工作。RSA就是他們三人姓氏開頭字母拼在一起組成的。

      假如有人找到一種快速因數分解的算法的話,那么用RSA加密的信息的可靠性就肯定會極度下降。但找到這樣的算法的可能性是非常小的。今天只有短的RSA鑰匙才可能被強力方式解破。到目前為止,世界上還沒有任何可靠的攻擊RSA算法的方式。只要其鑰匙的長度足夠長,用RSA加密的信息實際上是不能被解破的。

      1983年麻省理工學院在美國為RSA算法申請了專利。這個專利2000年9月21日失效。由于該算法在申請專利前就已經被發(fā)表了,在世界上大多數其它地區(qū)這個專利權不被承認。

      RSA應用過程

      非對稱算法的在應用的過程如下:

      • 接收方生成公鑰和私鑰,公鑰公開,私鑰保留;
      • 發(fā)送方將要發(fā)送的消息采用公鑰加密,得到密文,然后將密文發(fā)送給接收方;
      • 接收方收到密文后,用自己的私鑰進行解密,獲得明文。

      RSA工具類

      package com.demo.utils;import java.util.Map;@Slf4jpublic class RSAUtils { public static final String PUBLIC_KEY = “public_key”; public static final String PRIVATE_KEY = “private_key”; public static Map generateRasKey() { Map rs = new HashMap(); try { // KeyPairGenerator類用于生成公鑰和私鑰對,基于RSA算法生成對象 KeyPairGenerator keyPairGen = null; keyPairGen = KeyPairGenerator.getInstance(“RSA”); keyPairGen.initialize(1024, new SecureRandom()); // 生成一個密鑰對,保存在keyPair中 KeyPair keyPair = keyPairGen.generateKeyPair(); // 得到私鑰 公鑰 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded())); // 得到私鑰字符串 String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded()))); // 將公鑰和私鑰保存到Map rs.put(PUBLIC_KEY, publicKeyString); rs.put(PRIVATE_KEY, privateKeyString); } catch (Exception e) { log.error(“RsaUtils invoke genKeyPair failed.”, e); throw new RsaException(“RsaUtils invoke genKeyPair failed.”); } return rs; } public static String encrypt(String str, String publicKey) { try { //base64編碼的公鑰 byte[] decoded = Base64.decodeBase64(publicKey); RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(“RSA”).generatePublic(new X509EncodedKeySpec(decoded)); //RSA加密 Cipher cipher = Cipher.getInstance(“RSA”); cipher.init(Cipher.ENCRYPT_MODE, pubKey); return Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8))); } catch (Exception e) { log.error(“RsaUtils invoke encrypt failed.”, e); throw new RsaException(“RsaUtils invoke encrypt failed.”); } } public static String decrypt(String str, String privateKey) { try { //64位解碼加密后的字符串 byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8)); //base64編碼的私鑰 byte[] decoded = Base64.decodeBase64(privateKey); RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(“RSA”).generatePrivate(new PKCS8EncodedKeySpec(decoded)); //RSA解密 Cipher cipher = Cipher.getInstance(“RSA”); cipher.init(Cipher.DECRYPT_MODE, priKey); return new String(cipher.doFinal(inputByte)); } catch (Exception e) { log.error(“RsaUtils invoke decrypt failed.”, e); throw new RsaException(“RsaUtils invoke decrypt failed.”); } }}

      RsaException: 是自定義異常

      @Getterpublic class RsaException extends RuntimeException { private final String message; public RsaException(String message) { this.message = message; }}

      1.2.4 UT

      package com.rosh;public class RsaTest { /** * 用測試生成的公鑰,私鑰賦值 */ private static final String PUBLIC_KEY = “MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCFtTlL61IqIGd+fRLUhJ0MjsqFXFJswCohJ45m51WvbxDPRP3gllW0WChk74D5JEOpMDSWo4C7RfoGlBRNW7kQ6qYGukYZ5jgYpzoT0+gp3on96fQXEyQJysv9xiTPIdmSXXVVj1HAOJw29RbzxIVKUSzzPXvEtXRTtCC1+wkAJQIDAQAB”; private static final String PRIVATE_KEY = “MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAIW1OUvrUiogZ359EtSEnQyOyoVcUmzAKiEnjmbnVa9vEM9E/eCWVbRYKGTvgPkkQ6kwNJajgLtF+gaUFE1buRDqpga6RhnmOBinOhPT6Cneif3p9BcTJAnKy/3GJM8h2ZJddVWPUcA4nDb1FvPEhUpRLPM9e8S1dFO0ILX7CQAlAgMBAAECgYBC4amtbiKFa/wY61tV7pfYRjzLhKi+OUlZmD3E/4Z+4KGZ7DrJ8qkgMtDR3HO5LAikQrare1HTW2d7juqw32ascu+uDObf4yrYNKin+ZDLUYvIDfLhThPxnZJwQ/trdtfxO3VM//XbwZacmwYbAsYW/3QPUXwwOPAgbC2oth8kqQJBANKLyXcdjZx4cwJVl7xNeC847su8y6bPpcBASsaQloCIPiNBIg1h76dpfEGIQBYWJWbBsxtHe/MhOmz7fNFDS2sCQQCiktYZR0dZNH4eNX329LoRuBiltpr9tf36rVOlKr1GSHkLYEHF2qtyXV2mdrY8ZWpvuo3qm1oSLaqmop2rN9avAkBHk85B+IIUF77BpGeZVJzvMOO9z8lMRHuNCE5jgvQnbinxwkrZUdovh+T+QlvHJnBApslFFOBGn51FP5oHamFRAkEAmwZmPsinkrrpoKjlqz6GyCrC5hKRDWoj/IyXfKKaxpCJTH3HeoIghvfdO8Vr1X/n1Q8SESt+4mLFngznSMQAZQJBAJx07bCFYbA2IocfFV5LTEYTIiUeKdue2NP2yWqZ/+tB5H7jNwQTJmX1mn0W/sZm4+nJM7SjfETpNZhH49+rV6U=”; /** * 生成公鑰私鑰 */ @Test public void generateRsaKey() { Map map = RSAUtils.generateRasKey(); System.out.println(“隨機生成的公鑰為:” + map.get(RSAUtils.PUBLIC_KEY)); System.out.println(“隨機生成的私鑰為:” + map.get(RSAUtils.PRIVATE_KEY)); } /** * 加密: Yeidauky/iN1/whevov2+ntzXJKAp2AHfESu5ixnDqH5iB7ww+TcfqJpDfkPHfb12Y0sVXw0gBHNJ4inkh7l2/SJBze3pKQU/mg3oyDokTia3JZIs+e80/iJcSfN+yA1JaqY+eJPYiBiOGAF2S6x0ynvJg/Wj0fwp2Tq3PDzRMo= */ @Test public void testEncrypt() { JSONObject jsonObject = new JSONObject(); jsonObject.put(“username”, “rosh”); jsonObject.put(“password”, “123456”); String str = jsonObject.toJSONString(); String encrypt = RSAUtils.encrypt(str, PUBLIC_KEY); System.out.println(encrypt); } @Test public void testDecrypt() { String decrypt = RSAUtils.decrypt(“Yeidauky/iN1/whevov2+ntzXJKAp2AHfESu5ixnDqH5iB7ww+TcfqJpDfkPHfb12Y0sVXw0gBHNJ4inkh7l2/SJBze3pKQU/mg3oyDokTia3JZIs+e80/iJcSfN+yA1JaqY+eJPYiBiOGAF2S6x0ynvJg/Wj0fwp2Tq3PDzRMo=”, PRIVATE_KEY); System.out.println(decrypt); }}

      案例

      SpringCloud Gateway + SpringBoot + Nacos+redis

      前端登錄代碼

      后端把公鑰跟前端約定好:

      登錄頁面

      登錄

      賬號: 密碼:

      前端查詢代碼

      設定公鑰、token,token是登錄成功后返回的值

      查詢測試id:

      GatewayFilterConfig

      解密前端傳來的參數并修改傳參

      package com.demo.gateway.config;public class GatewayFilterConfig implements GlobalFilter, Ordered { @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { //1 如果是登錄不校驗Token String requestUrl = exchange.getRequest().getPath().value(); AntPathMatcher pathMatcher = new AntPathMatcher(); if (!pathMatcher.match(“/user/login”, requestUrl)) { String token = exchange.getRequest().getHeaders().getFirst(UserConstant.TOKEN); Claims claim = TokenUtils.getClaim(token); if (StringUtils.isBlank(token) || claim == null) { return FilterUtils.invalidToken(exchange); } } //2 修改請求參數,并獲取請求參數 try { updateRequestParam(exchange); } catch (Exception e) { return FilterUtils.invalidUrl(exchange); } //3 獲取請求體,修改請求體 ServerRequest serverRequest = ServerRequest.create(exchange, HandlerStrategies.withDefaults().messageReaders()); Mono modifiedBody = serverRequest.bodyToMono(String.class).flatMap(body -> { String encrypt = RSAUtils.decrypt(body, RSAConstant.PRIVATE_KEY); return Mono.just(encrypt); }); //創(chuàng)建BodyInserter修改請求體 BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class); HttpHeaders headers = new HttpHeaders(); headers.putAll(exchange.getRequest().getHeaders()); headers.remove(HttpHeaders.CONTENT_LENGTH); //創(chuàng)建CachedBodyOutputMessage并且把請求param加入 CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers); return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> { ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.getRequest()) { @Override public Flux getBody() { return outputMessage.getBody(); } }; return chain.filter(exchange.mutate().request(decorator).build()); })); } /** * 修改前端傳的參數 */ private void updateRequestParam(ServerWebExchange exchange) throws NoSuchFieldException, IllegalAccessException { ServerHttpRequest request = exchange.getRequest(); URI uri = request.getURI(); String query = uri.getQuery(); if (StringUtils.isNotBlank(query) && query.contains(“param”)) { String[] split = query.split(“=”); String param = RSAUtils.decrypt(split[1], RSAConstant.PRIVATE_KEY); Field targetQuery = uri.getClass().getDeclaredField(“query”); targetQuery.setAccessible(true); targetQuery.set(uri, param); } } @Override public int getOrder() { return 80; }}

      GateWay 統一異常

      public abstract class AbstractExceptionHandler { protected JSONObject buildErrorMap(Throwable ex) { JSONObject json = new JSONObject(); if (ex instanceof RSAException || ex instanceof IllegalArgumentException) { json.put(“code”, HttpStatus.BAD_REQUEST.value()); if (StringUtils.isNotBlank(ex.getMessage())){ json.put(“msg”, ex.getMessage()); }else { json.put(“msg”, “無效的請求”); } } else { json.put(“code”, HttpStatus.BAD_REQUEST.value()); json.put(“msg”, “未知錯誤聯系管理員”); } return json; }}@Configurationpublic class GatewayExceptionConfig { @Primary @Bean @Order(Ordered.HIGHEST_PRECEDENCE) public ErrorWebExceptionHandler errorWebExceptionHandler(ObjectProvider viewResolversProvider, ServerCodecConfigurer serverCodecConfigurer) { GatewayExceptionHandler gatewayExceptionHandler = new GatewayExceptionHandler(); gatewayExceptionHandler.setViewResolvers(viewResolversProvider.getIfAvailable(Collections::emptyList)); gatewayExceptionHandler.setMessageWriters(serverCodecConfigurer.getWriters()); gatewayExceptionHandler.setMessageReaders(serverCodecConfigurer.getReaders()); return gatewayExceptionHandler; }}package com.demo.gateway.exception;import com.alibaba.fastjson.JSONObject;import lombok.extern.slf4j.Slf4j;import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;import org.springframework.http.HttpStatus;import org.springframework.http.MediaType;import org.springframework.http.codec.HttpMessageReader;import org.springframework.http.codec.HttpMessageWriter;import org.springframework.util.Assert;import org.springframework.web.reactive.function.BodyInserters;import org.springframework.web.reactive.function.server.RequestPredicates;import org.springframework.web.reactive.function.server.RouterFunctions;import org.springframework.web.reactive.function.server.ServerRequest;import org.springframework.web.reactive.function.server.ServerResponse;import org.springframework.web.reactive.result.view.ViewResolver;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;import java.util.Collections;import java.util.List;import java.util.Map;@Slf4jpublic class GatewayExceptionHandler extends AbstractExceptionHandler implements ErrorWebExceptionHandler { private List messageReaders = Collections.emptyList(); private List messageWriters = Collections.emptyList(); private List viewResolvers = Collections.emptyList(); private ThreadLocal exceptionHandlerResult = new ThreadLocal(); public void setMessageReaders(List messageReaders) { Assert.notNull(messageReaders, “‘messageReaders’ must not be null”); this.messageReaders = messageReaders; } public void setViewResolvers(List viewResolvers) { this.viewResolvers = viewResolvers; } public void setMessageWriters(List messageWriters) { Assert.notNull(messageWriters, “‘messageWriters’ must not be null”); this.messageWriters = messageWriters; } @Override public Mono handle(ServerWebExchange exchange, Throwable ex) { JSONObject errorInfo = super.buildErrorMap(ex); if (exchange.getResponse().isCommitted()) { return Mono.error(ex); } exceptionHandlerResult.set(errorInfo); ServerRequest newRequest = ServerRequest.create(exchange, this.messageReaders); return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse).route(newRequest) .switchIfEmpty(Mono.error(ex)) .flatMap(handler -> handler.handle(newRequest)) .flatMap(response -> write(exchange, response)); } protected Mono renderErrorResponse(ServerRequest request) { Map result = exceptionHandlerResult.get(); return ServerResponse.status(HttpStatus.OK) .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromValue(result)); } private Mono write(ServerWebExchange exchange, ServerResponse response) { exchange.getResponse().getHeaders().setContentType(response.headers().getContentType()); return response.writeTo(exchange, new ResponseContext()); } private class ResponseContext implements ServerResponse.Context { @Override public List messageWriters() { return GatewayExceptionHandler.this.messageWriters; } @Override public List viewResolvers() { return GatewayExceptionHandler.this.viewResolvers; } }}

      JAVA業(yè)務代碼

      @RestController@RequestMapping(“/user”)public class UserController { @Autowired private UserService userService; @PostMapping(“/login”) public String login(@RequestBody UserForm userForm) { return userService.login(userForm); } @GetMapping(“/detail”) public JSONObject detail(@RequestParam(“id”) Long id) { return userService.detail(id); }}@Servicepublic class UserService { private static final String USERNAME = “admin”; private static final String PASSWORD = “123456”; private static final Long USER_ID = 1L; /** * 模擬 登錄 username = admin, password =123456,user_id 1L 登錄成功 返回token */ public String login(UserForm userForm) { String username = userForm.getUsername(); String password = userForm.getPassword(); if (USERNAME.equals(username) && PASSWORD.equals(password)) { JSONObject userInfo = new JSONObject(); userInfo.put(“username”, USERNAME); userInfo.put(“password”, PASSWORD); userInfo.put(“userId”, USER_ID); return TokenUtils.createToken(userInfo.toJSONString()); } return “賬號密碼不正確”; } public JSONObject detail(Long id) { JSONObject jsonObject = new JSONObject(); jsonObject.put(“id”, id); jsonObject.put(“name”, “admin”); return jsonObject; }}

      測試

      登錄:返回token

      查詢:

      設置URL有效時長

      為了增強URL安全性,前端在header中添加時間戳。

      前端代碼

      在header中添加時間戳

      2.2 后端驗證時間戳

      private Long getDateTimestamp(HttpHeaders httpHeaders) { List list = httpHeaders.get(“timestamp”); if (CollectionUtils.isEmpty(list)) { throw new IllegalArgumentException(“拒絕服務”); } long timestamp = Long.parseLong(list.get(0)); long currentTimeMillis = System.currentTimeMillis(); //有效時長為5分鐘 if (currentTimeMillis – timestamp > 1000 * 60 * 5) { throw new IllegalArgumentException(“拒絕服務”); } return timestamp; }

      測試不傳時間戳

      確保URL唯一性

      確保URL唯一性,前端請求中增加UUID,后端存入redis,有效時長為5分鐘,5分鐘重復提交拒絕服務

      修改前端請求參數

      3.2 后端增加驗證RequestId

      private String getRequestId(HttpHeaders headers) { List list = headers.get(“requestId”); if (CollectionUtils.isEmpty(list)) { throw new IllegalArgumentException(ERROR_MESSAGE); } String requestId = list.get(0); //如果requestId存在redis中直接返回 String temp = redisTemplate.opsForValue().get(requestId); if (StringUtils.isNotBlank(temp)) { throw new IllegalArgumentException(ERROR_MESSAGE); } redisTemplate.opsForValue().set(requestId, requestId, 5, TimeUnit.MINUTES); return requestId; }

      增加簽名

      最后一步,添加簽名

      前端增加簽名

      跟前端約定好,json數據按照ASCII升序排序。

      登錄頁面:

      登錄頁面

      登錄

      賬號: 密碼:

      增強讀取Body類

      /** * @Description: * @Author: Rosh * @Date: 2021/10/27 11:03 */public class MyCachedBodyOutputMessage extends CachedBodyOutputMessage { private Map paramMap; private Long dateTimestamp; private String requestId; private String sign; public MyCachedBodyOutputMessage(ServerWebExchange exchange, HttpHeaders httpHeaders) { super(exchange, httpHeaders); } public void initial(Map paramMap, String requestId, String sign, Long dateTimestamp) { this.paramMap = paramMap; this.requestId = requestId; this.sign = sign; this.dateTimestamp = dateTimestamp; } public Map getParamMap() { return paramMap; } public Long getDateTimestamp() { return dateTimestamp; } public String getRequestId() { return requestId; } public String getSign() { return sign; }}

      4.3 修改GatewayFilterConfig

      package com.demo.gateway.config;public class GatewayFilterConfig implements GlobalFilter, Ordered { @Autowired private RedisTemplate redisTemplate; private static final String ERROR_MESSAGE = “拒絕服務”; @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { //1 獲取時間戳 Long dateTimestamp = getDateTimestamp(exchange.getRequest().getHeaders()); //2 獲取RequestId String requestId = getRequestId(exchange.getRequest().getHeaders()); //3 獲取簽名 String sign = getSign(exchange.getRequest().getHeaders()); //4 如果是登錄不校驗Token String requestUrl = exchange.getRequest().getPath().value(); AntPathMatcher pathMatcher = new AntPathMatcher(); if (!pathMatcher.match(“/user/login”, requestUrl)) { String token = exchange.getRequest().getHeaders().getFirst(UserConstant.TOKEN); Claims claim = TokenUtils.getClaim(token); if (StringUtils.isBlank(token) || claim == null) { return FilterUtils.invalidToken(exchange); } } //5 修改請求參數,并獲取請求參數 Map paramMap; try { paramMap = updateRequestParam(exchange); } catch (Exception e) { return FilterUtils.invalidUrl(exchange); } //6 獲取請求體,修改請求體 ServerRequest serverRequest = ServerRequest.create(exchange, HandlerStrategies.withDefaults().messageReaders()); Mono modifiedBody = serverRequest.bodyToMono(String.class).flatMap(body -> { String encrypt = RSAUtils.decrypt(body, RSAConstant.PRIVATE_KEY); JSONObject jsonObject = JSON.parseObject(encrypt); for (Map.Entry entry : jsonObject.entrySet()) { paramMap.put(entry.getKey(), entry.getValue()); } checkSign(sign, dateTimestamp, requestId, paramMap); return Mono.just(encrypt); }); //創(chuàng)建BodyInserter修改請求體 BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class); HttpHeaders headers = new HttpHeaders(); headers.putAll(exchange.getRequest().getHeaders()); headers.remove(HttpHeaders.CONTENT_LENGTH); //創(chuàng)建CachedBodyOutputMessage并且把請求param加入,初始化校驗信息 MyCachedBodyOutputMessage outputMessage = new MyCachedBodyOutputMessage(exchange, headers); outputMessage.initial(paramMap, requestId, sign, dateTimestamp); return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> { ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.getRequest()) { @Override public Flux getBody() { Flux body = outputMessage.getBody(); if (body.equals(Flux.empty())) { //驗證簽名 checkSign(outputMessage.getSign(), outputMessage.getDateTimestamp(), outputMessage.getRequestId(), outputMessage.getParamMap()); } return outputMessage.getBody(); } }; return chain.filter(exchange.mutate().request(decorator).build()); })); } public void checkSign(String sign, Long dateTimestamp, String requestId, Map paramMap) { String str = JSON.toJSONString(paramMap) + requestId + dateTimestamp; String tempSign = Md5Utils.getMD5(str.getBytes()); if (!tempSign.equals(sign)) { throw new IllegalArgumentException(ERROR_MESSAGE); } } /** * 修改前端傳的參數 */ private Map updateRequestParam(ServerWebExchange exchange) throws NoSuchFieldException, IllegalAccessException { ServerHttpRequest request = exchange.getRequest(); URI uri = request.getURI(); String query = uri.getQuery(); if (StringUtils.isNotBlank(query) && query.contains(“param”)) { String[] split = query.split(“=”); String param = RSAUtils.decrypt(split[1], RSAConstant.PRIVATE_KEY); Field targetQuery = uri.getClass().getDeclaredField(“query”); targetQuery.setAccessible(true); targetQuery.set(uri, param); return getParamMap(param); } return new TreeMap(); } private Map getParamMap(String param) { Map map = new TreeMap(); String[] split = param.split(“&”); for (String str : split) { String[] params = str.split(“=”); map.put(params[0], params[1]); } return map; } private String getSign(HttpHeaders headers) { List list = headers.get(“sign”); if (CollectionUtils.isEmpty(list)) { throw new IllegalArgumentException(ERROR_MESSAGE); } return list.get(0); } private Long getDateTimestamp(HttpHeaders httpHeaders) { List list = httpHeaders.get(“timestamp”); if (CollectionUtils.isEmpty(list)) { throw new IllegalArgumentException(ERROR_MESSAGE); } long timestamp = Long.parseLong(list.get(0)); long currentTimeMillis = System.currentTimeMillis(); //有效時長為5分鐘 if (currentTimeMillis – timestamp > 1000 * 60 * 5) { throw new IllegalArgumentException(ERROR_MESSAGE); } return timestamp; } private String getRequestId(HttpHeaders headers) { List list = headers.get(“requestId”); if (CollectionUtils.isEmpty(list)) { throw new IllegalArgumentException(ERROR_MESSAGE); } String requestId = list.get(0); //如果requestId存在redis中直接返回 String temp = redisTemplate.opsForValue().get(requestId); if (StringUtils.isNotBlank(temp)) { throw new IllegalArgumentException(ERROR_MESSAGE); } redisTemplate.opsForValue().set(requestId, requestId, 5, TimeUnit.MINUTES); return requestId; } @Override public int getOrder() { return 80; }}

      測試登錄

      發(fā)現驗簽成功

      測試查詢

      驗簽成功

      地址

      https://gitee.com/zhurongsheng/springcloud-gateway-rsa

      鄭重聲明:本文內容及圖片均整理自互聯網,不代表本站立場,版權歸原作者所有,如有侵權請聯系管理員(admin#wlmqw.com)刪除。
      用戶投稿
      上一篇 2022年6月21日 06:37
      下一篇 2022年6月21日 06:37

      相關推薦

      • 存儲過程語法(sql server存儲過程語法)

        今天小編給各位分享存儲過程語法的知識,其中也會對sql server存儲過程語法進行解釋,如果能碰巧解決你現在面臨的問題,別忘了關注本站,現在開始吧! oracle存儲過程基本語法…

        2022年11月26日
      • 計算機網絡技術論文(計算機網絡技術論文七千字)

        今天小編給各位分享計算機網絡技術論文的知識,其中也會對計算機網絡技術論文七千字進行解釋,如果能碰巧解決你現在面臨的問題,別忘了關注本站,現在開始吧! 計算機網絡方面的論文3000字…

        2022年11月26日
      • 《萬里歸途》密鑰延期至12月31日 目前票房15.65億

        11月22日,由饒曉志執(zhí)導,張譯、王俊凱、殷桃主演的電影《萬里歸途》宣布密鑰將延期至12月31日。 《萬里歸途》宣布密鑰將延期至12月31日。 據燈塔專業(yè)版數據,該片上映54天,票…

        2022年11月25日
      • 百度關鍵詞快速排名的4大原理解析(百度怎么刷關鍵詞)

        近期百度公告驚雷算法2.0,升級之快還是第一次吧,看來百度對于刷點擊行為是零容忍了。之前尹華峰SEO技術博客介紹過一篇如何使用刷點擊工具,其實市面上有很多這類SEO快速排名的軟件,…

        2022年11月25日
      • 博客營銷的3大優(yōu)勢解析(博客營銷怎么做)

        不知不覺已經寫了24篇文章,加上這篇是第25篇了,都是自己這幾年來用過的營銷方法,如果遇到有些不懂的,我會咨詢我的朋友和同事幫忙,盡量讓每一篇有價值,哪怕是對大家有一點點幫助也行,…

        2022年11月25日
      • 2022全球最常用密碼名單:password成全球最常用密碼

        11月24日消息,據IT之家報道,密碼管理工具NordPass現已發(fā)布2022年全球最常用的密碼名單,結果顯示用戶仍在使用眾所周知的弱密碼。統計數據顯示,今年全球最常見的密碼是“p…

        2022年11月25日
      • 成都健康碼打不開顯示接口請求未知異常怎么辦(成都健康碼打不開顯示接口請求未知異常)

        成都這幾天的疫情也是備受關注,疫情期間各地出行都是需要查看健康碼的,不過今天卻有成都的小伙伴反饋健康碼無法打開的情況。成都健康碼打不開顯示接口請求未知異常怎么辦?由于健康碼無法打開…

        2022年11月24日
      • 銳龍97900x參數規(guī)格跑分評測 銳龍97900x屬于什么檔次

        銳龍9 7900X是銳龍7000系列處理器中性能頂尖的型號之一,它采用了這一代標配的zen4架構和5nm制程工藝,那么它具體的參數跑分如何,在電腦上世紀發(fā)揮怎么樣呢,下面就來看看銳…

        2022年11月24日
      • 前三季度,市場規(guī)模超過五萬億元 信息消費展現蓬勃生機

        家居企業(yè)個性化全屋定制系統,備受消費者青睞;主打專業(yè)電競的新款高性能便攜式計算機,銷量表現創(chuàng)新高;物流企業(yè)推出數智化供應鏈興農服務項目,助力優(yōu)質農產品出深山…… 不久前,工信部發(fā)布…

        2022年11月24日
      • 微信微店怎么開

        微信開店的方式有以下兩種1基于微信公眾號搭建一個“微商城”2基于微信小程序,搭建一個商城型小程序下面給你介紹一下具體的流程 1登錄微信公眾平臺,申請注冊一個微信公眾號,或者直接注冊…

        2022年11月24日

      聯系我們

      聯系郵箱:admin#wlmqw.com
      工作時間:周一至周五,10:30-18:30,節(jié)假日休息