亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

gateway和jwt網(wǎng)關(guān)認證實現(xiàn)過程解析

 更新時間:2019年11月13日 11:11:43   作者:老人與JAVA  
這篇文章主要介紹了gateway和jwt網(wǎng)關(guān)認證實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

這篇文章主要介紹了gateway和jwt網(wǎng)關(guān)認證實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

思路: 全局過濾器對所有的請求攔截(生成token有效期30分鐘,放入redis設(shè)置有效期3天。3天之類可以通過刷新接口自動刷新,超過3天需要重新登錄。)

前端在調(diào)用接口之前先判斷token是否過期(3o分鐘),過期則先調(diào)刷新接口,換取新token,

1引入相關(guān)jar

<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
      <groupId>io.jsonwebtoken</groupId>
      <artifactId>jjwt</artifactId>
      <version>0.9.0</version>
</dependency>

2編寫Jwt工具類(生成token + 解析token)

package spring.cloud.gateway.common;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.util.StringUtils;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

public class JwtUtil {
  public static final String SECRET = "qazwsx123444$#%#()*&& asdaswwi1235 ?;!@#kmmmpom in***xx**&";
  public static final String TOKEN_PREFIX = "Bearer";
  public static final String LOGIN_URL = "/token/userId/pwd";
  public static final String LOGOUT_URL = "/token/userId";
  public static final String HEADER_AUTH = "authorization";
  public static final String HEADER_USERID = "userid";
  //token超時時間
  public static final int TOKEN_EXPIRATION_MINUTE = 30;
  //token的redis超時時間
  public static final int TOKEN_REDIS_EXPIRATION_DAY = 7;

  
  public static String generateToken(String userId) {
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.MINUTE, TOKEN_EXPIRATION_MINUTE); //得到前一天
    Date date = calendar.getTime();
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    df.format(date);
    //todo 優(yōu)化token的生層規(guī)則
    HashMap<String, Object> map = new HashMap<>();
    map.put(HEADER_USERID, userId);
    String jwt = Jwts.builder()
        .setSubject(HEADER_USERID).setClaims(map)
        .setExpiration(date)
        .signWith(SignatureAlgorithm.HS512, SECRET)
        .compact();
    return TOKEN_PREFIX + " " + jwt;
  }

  public static Map<String, String> validateToken(String token) {
    HashMap<String, String> tokenMap = new HashMap<String, String>();
    if (StringUtils.isEmpty(token)) {
      return tokenMap;
    }
    try {
      Map<String, Object> tokenBody = Jwts.parser()
          .setSigningKey(SECRET)
          .parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
          .getBody();
      String userId = String.valueOf(tokenBody.get(HEADER_USERID));
      tokenMap.put(HEADER_USERID, userId);
    }catch (ExpiredJwtException e){
      e.printStackTrace();
    }
    return tokenMap;
  }

  /**
   * 移到j(luò)wtUtil中去
   *
   * @param token
   * @return
   */
  public static Map<String, String> validateTokenAndUser(String token, String userIdIn) {
    Map<String, String> tokenResultMap = new HashMap<>();
    if (StringUtils.isEmpty(token) || StringUtils.isEmpty(userIdIn)) {
      return tokenResultMap;
    }
    tokenResultMap = validateToken(token);
    if (StringUtils.isEmpty(token) || StringUtils.isEmpty(userIdIn)) {
      return tokenResultMap;
    }
    //判斷傳入的userid和token是否匹配
    String userIdOri = tokenResultMap.get(HEADER_USERID);
    if (!userIdIn.equals(userIdOri)) {
      return new HashMap<String,String>();
    }
    return tokenResultMap;
  }

}

3編寫過濾器類

package spring.cloud.gateway.filter;

import java.net.URI;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.PathContainer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import spring.cloud.gateway.common.JwtUtil;
import spring.cloud.gateway.exception.PermissionException;

/**
 * 參數(shù)參考 https://blog.csdn.net/tianyaleixiaowu/article/details/83375246
 * response參考 https://bbs.csdn.net/topics/392412604?list=11074255
 */
@Component
public class AuthFilter implements GlobalFilter {

  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    ServerHttpRequest request = exchange.getRequest();
    HttpHeaders header = request.getHeaders();
    HttpMethod method = request.getMethod();
    String token = header.getFirst(JwtUtil.HEADER_AUTH);
    String userId = header.getFirst(JwtUtil.HEADER_USERID);
    PathContainer pathContainer = request.getPath().pathWithinApplication();
    String path = pathContainer.value();

    //2- 處理登錄請求
    if (StringUtils.isBlank(token)) {
      //是登錄接口則放行,否則返回異常
      if (path.contains(JwtUtil.LOGIN_URL) && HttpMethod.POST.equals(method)) {
        throw new PermissionException("please login");
      }
      return chain.filter(exchange);
    }

    //3- 處理刷新token請求
    if (path.indexOf("refresh") >= 0) {
      //放行去掉刷新接口(在刷新前校驗userId和token是否匹配)
      return chain.filter(exchange);
    }

    //4- 處理刷新token請求
    if (path.contains(JwtUtil.LOGOUT_URL) && HttpMethod.DELETE.equals(method)) {
      //放行去掉登出接口(在刷新前校驗userId和token是否匹配)
      return chain.filter(exchange);
    }

    //5- 攜帶token請求其他業(yè)務(wù)接口
    Map<String, String> validateResultMap = JwtUtil.validateTokenAndUser(token, userId);
    if (validateResultMap == null || validateResultMap.isEmpty()) {
      throw new PermissionException("token 已經(jīng)失效");
    }
    // TODO 將用戶信息存放在請求header中傳遞給下游業(yè)務(wù)
    Route gatewayUrl = exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
    URI uri = gatewayUrl.getUri();
    //表示下游請求對應(yīng)的服務(wù)名如 SPRING-CLOUD-SERVICE SPRING-CLOUD-GATEWAY
    String serviceName = uri.getHost();

    ServerHttpRequest.Builder mutate = request.mutate();
    mutate.header("x-user-id", validateResultMap.get("userid"));
    mutate.header("x-user-name", validateResultMap.get("user"));
    mutate.header("x-user-serviceName", serviceName);
    ServerHttpRequest buildReuqest = mutate.build();

    //todo 如果響應(yīng)中需要放數(shù)據(jù),也可以放在response的header中
    //ServerHttpResponse response = exchange.getResponse();
    //response.getHeaders().add("new_token","token_value");
    return chain.filter(exchange.mutate().request(buildReuqest).build());
  }
}

4編寫相關(guān)接口API

package spring.cloud.gateway.controller;
import org.springframework.web.bind.annotation.*;
import spring.cloud.gateway.common.JwtUtil;
import java.util.Map;
@RestController
@RequestMapping("/token")
public class TokenController {

  /**
   * 登錄接口
   * @param user(userID +pwd)
   * @return
   */
  @PostMapping("/userId/pwd")
  public String getToken(@RequestBody Map<String,String> user) {
    //用戶名密碼需要加密處理
    String result = "";
    if (user == null || user.isEmpty()) {
      return result;
    }
    String userId = user.get("userId");
    String pwd = user.get("pwd");
    if (!doLogin(userId,pwd)) {
      return result;
    }
    String token = JwtUtil.generateToken(userId);
    // todo 將token放入redis中,設(shè)置超時時間為 2 * t
    return token;
  }

  private Boolean doLogin(String userId,String pwd) {
    //后續(xù)對接user表驗證
    if ("admin".equals(userId) && "123".equals(pwd)) {
      return true;
    }
    if ("spring".equals(userId) && "123".equals(pwd)) {
      return true;
    }
    if ("gateway".equals(userId) && "123".equals(pwd)) {
      return true;
    }
    return false;
  }
  /**
   * 登出接口
   */
  /**
   * 刷新token的接口
   * 在刷新前校驗userId和token是否匹配
   */
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • springmvc實現(xiàn)json交互-requestBody和responseBody

    springmvc實現(xiàn)json交互-requestBody和responseBody

    本文主要介紹了springmvc實現(xiàn)json交互-requestBody和responseBody的相關(guān)知識。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03
  • 關(guān)于java中Map的九大問題分析

    關(guān)于java中Map的九大問題分析

    這篇文章主要為大家詳細分析了關(guān)于java中Map的九大問題,感興趣的小伙伴們可以參考一下
    2016-08-08
  • Java輸出打印工具類封裝的實例

    Java輸出打印工具類封裝的實例

    下面小編就為大家?guī)硪黄狫ava輸出打印工具類封裝的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • JMS簡介與ActiveMQ實戰(zhàn)代碼分享

    JMS簡介與ActiveMQ實戰(zhàn)代碼分享

    這篇文章主要介紹了JMS簡介與ActiveMQ實戰(zhàn)代碼分享,具有一定借鑒價值,需要的朋友可以參考下
    2017-12-12
  • Java線上問題排查神器Arthas實戰(zhàn)原理解析

    Java線上問題排查神器Arthas實戰(zhàn)原理解析

    原先我們Java中我們常用分析問題一般是使用JDK自帶或第三方的分析工具如jstat、jmap、jstack、?jconsole、visualvm、Java?Mission?Control、MAT等,還有一款神器Arthas工具,可幫助程序員解決很多繁瑣的問題,感興趣的朋友一起看看吧
    2022-01-01
  • Spring Boot使用Redisson實現(xiàn)滑動窗口限流的項目實踐

    Spring Boot使用Redisson實現(xiàn)滑動窗口限流的項目實踐

    滑動窗口限流是一種流量控制策略,用于控制在一定時間內(nèi)的請求頻率,本文主要介紹了Spring Boot使用Redisson實現(xiàn)滑動窗口限流的項目實踐,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • java中final與finally的使用介紹

    java中final與finally的使用介紹

    本篇文章介紹了,在java中final與finally的使用。需要的朋友參考下
    2013-04-04
  • Java字節(jié)碼ByteBuddy使用及原理解析上

    Java字節(jié)碼ByteBuddy使用及原理解析上

    這篇文章主要為大家介紹了Java字節(jié)碼ByteBuddy使用及原理解析上篇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • SpringBoot 異步線程間數(shù)據(jù)傳遞的實現(xiàn)

    SpringBoot 異步線程間數(shù)據(jù)傳遞的實現(xiàn)

    本文主要介紹了SpringBoot 異步線程間數(shù)據(jù)傳遞的實現(xiàn),包括異步線程的基本概念、數(shù)據(jù)傳遞的方式、具體實現(xiàn)方式等,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • Java中UUID生成原理及優(yōu)缺點

    Java中UUID生成原理及優(yōu)缺點

    本文將詳細講解UUID的生成原理、特性、實用場景以及優(yōu)缺點,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06

最新評論