最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Cloud Gateway 使用JWT工具類做用戶登錄校驗功能

 更新時間:2021年01月26日 14:22:30   作者:興趣使然的草帽路飛  
這篇文章主要介紹了Spring Cloud Gateway 使用JWT工具類做用戶登錄校驗的示例代碼,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

1. JWT測試

/**
 * @Auther: csp1999
 * @Date: 2021/01/24/19:29
 * @Description: JWT測試
 */
public class JwtTest {

 /**
  * 創(chuàng)建Jwt令牌:
  *
  * JWT = 頭部Header + 載荷playload + 簽名signature
  */
 @Test
 public void testCreateJwt() {
  // 構建jwt令牌
  // 1.頭部Header: 描述關于該JWT的最基本的信息,例如其類型以及簽名所用的算法等
  JwtBuilder builder = Jwts.builder()
    .setId("8989")      // 設置令牌唯一編號
    .setIssuer("csp1999")    // 設置令牌頒發(fā)者
    .setSubject("JWT加密測試")   // 設置令牌主題 可以是JSON數據
    .setIssuedAt(new Date())   // 設置令牌簽發(fā)日期
    .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 3));// 設置令牌過期時間 3分鐘

  // 2.自定義載荷playload: 存放有效信息的地方
  Map<String,Object> userInfo = new HashMap<>();
  userInfo.put("username","csp");
  userInfo.put("password","123456");
  userInfo.put("school","河南科技大學");
  userInfo.put("age","22");
  // 將載荷添加到JWT令牌中
  builder.addClaims(userInfo);

  // 3.為令牌設置 簽名signature
  builder.signWith(SignatureAlgorithm.HS256, "haust");// 設置令牌的簽名 使用HS256算法,并設置SecretKey密鑰(字符串)

  // 構建 并返回一個字符串
  String jwtStr = builder.compact();
  System.out.println(jwtStr);
 }

 /**
  * 解析Jwt令牌數據
  */
 @Test
 public void testParseJwt() {
  // jwt字符串
  String jwtStr = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4OTg5IiwiaXNzIjoiY3NwMTk5OSIsInN1YiI6IkpXVOWKoOWvhua1i-ivlSIsImlhdCI6MTYxMTQ4ODc1MSwiZXhwIjoxNjExNDg4OTMxLCJwYXNzd29yZCI6IjEyMzQ1NiIsInNjaG9vbCI6Iuays-WNl-enkeaKgOWkp-WtpiIsImFnZSI6IjIyIiwidXNlcm5hbWUiOiJjc3AifQ.uH28G9MSHfzaKBAOyr8AdksYLVvy8O5P8g7TORZIUFY";

  // 解析jwt字符串
  Claims claims = Jwts.parser().
    setSigningKey("haust").  // 密鑰(鹽)
    parseClaimsJws(jwtStr).  // 要解析的令牌對象
    getBody();     // 獲取解析后的結果

  // {jti=8989, iss=csp1999, sub=JWT加密測試, iat=1611488751, exp=1611488931, password=123456, school=河南科技大學, age=22, username=csp}
  System.out.println(claims);
 }
}

2. JWT工具類

/**
 * @Auther: csp1999
 * @Date: 2021/01/24/19:29
 * @Description: JWT工具類
 */
public class JwtUtil {
 // 有效期為
 public static final Long JWT_TTL = 3600000L;// 60 * 60 * 1000 一個小時

 // Jwt令牌信息
 public static final String JWT_KEY = "itcast";

 /**
  * 生成令牌
  * @param id
  * @param subject
  * @param ttlMillis
  * @return
  */
 public static String createJWT(String id, String subject, Long ttlMillis) {
  // 指定算法
  SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

  // 當前系統(tǒng)時間
  long nowMillis = System.currentTimeMillis();
  // 令牌簽發(fā)時間
  Date now = new Date(nowMillis);

  // 如果令牌有效期為null,則默認設置有效期1小時
  if (ttlMillis == null) {
   ttlMillis = JwtUtil.JWT_TTL;
  }

  // 令牌過期時間設置
  long expMillis = nowMillis + ttlMillis;
  Date expDate = new Date(expMillis);

  // 生成秘鑰
  SecretKey secretKey = generalKey();

  // 封裝Jwt令牌信息
  JwtBuilder builder = Jwts.builder()
    .setId(id)         //唯一的ID
    .setSubject(subject)      // 主題 可以是JSON數據
    .setIssuer("admin")       // 簽發(fā)者
    .setIssuedAt(now)       // 簽發(fā)時間
    .signWith(signatureAlgorithm, secretKey) // 簽名算法以及密匙
    .setExpiration(expDate);     // 設置過期時間

  return builder.compact();
 }

 /**
  * 生成加密 secretKey
  *
  * @return
  */
 public static SecretKey generalKey() {
  byte[] encodedKey = Base64.getEncoder().encode(JwtUtil.JWT_KEY.getBytes());
  SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
  return key;
 }


 /**
  * 解析令牌數據
  *
  * @param jwt
  * @return
  * @throws Exception
  */
 public static Claims parseJWT(String jwt) throws Exception {
  SecretKey secretKey = generalKey();
  return Jwts.parser()
    .setSigningKey(secretKey)
    .parseClaimsJws(jwt)
    .getBody();
 }

 public static void main(String[] args) {
  String jwt = JwtUtil.createJWT("weiyibiaoshi", "aaaaaa", null);

  System.out.println(jwt);
  try {
   Claims claims = JwtUtil.parseJWT(jwt);
   System.out.println(claims);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

3. 用戶登錄校驗

3.1 網關過濾器

/**
 * @Auther: csp1999
 * @Date: 2021/01/24/20:17
 * @Description: 授權過濾器
 */
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {

 // 令牌頭名字
 private static final String AUTHORIZE_TOKEN = "Authorization";

 /**
  * 全局過濾器
  *
  * @param exchange
  * @param chain
  * @return
  */
 @Override
 public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  // 獲取Request、Response對象
  ServerHttpRequest request = exchange.getRequest();
  ServerHttpResponse response = exchange.getResponse();

  // 獲取請求的URI
  String path = request.getURI().getPath();

  // 如果是登錄、goods等開放的微服務[這里的goods部分開放],則直接放行,這里不做完整演示,完整演示需要設計一套權限系統(tǒng)
  // 未登錄下只放行登錄和搜索
  if (path.startsWith("/api/user/login") || path.startsWith("/api/brand/search/")) {
   // 放行
   Mono<Void> filter = chain.filter(exchange);

   return filter;
  }

  // 從頭文件中獲取的令牌信息
  String token = request.getHeaders().getFirst(AUTHORIZE_TOKEN);
  // 如果為true:說明令牌在頭文件中, false:令牌不在頭文件中,將令牌封裝入頭文件,再傳遞給其他微服務
  boolean hasToken = true;

  // 如果頭文件中沒有令牌信息,則從請求參數中獲取
  if (StringUtils.isEmpty(token)) {
   token = request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
   hasToken = false;
  }

  // 如果為空,則輸出錯誤代碼
  if (StringUtils.isEmpty(token)) {
   // 設置方法不允許被訪問,405錯誤代碼
   response.setStatusCode(HttpStatus.METHOD_NOT_ALLOWED);
   return response.setComplete();
  }

  // 如果不為空,則解析令牌數據
  try {
   Claims claims = JwtUtil.parseJWT(token);
  } catch (Exception e) {
   e.printStackTrace();
   // 解析失敗,響應401錯誤
   response.setStatusCode(HttpStatus.UNAUTHORIZED);
   return response.setComplete();
  }

  // 放行之前,將令牌封裝到頭文件中(這一步是為了方便AUTH2校驗令牌)
  request.mutate().header(AUTHORIZE_TOKEN,token);

  // 放行
  return chain.filter(exchange);
 }


 /**
  * 過濾器執(zhí)行順序
  *
  * @return
  */
 @Override
 public int getOrder() {
  // 首位
  return 0;
 }
}

3.2 網關微服務application.yml

spring:
 cloud:
 gateway:
  globalcors:
  corsConfigurations:
   '[/**]': # 匹配所有請求
   allowedOrigins: "*" # 跨域處理 允許所有的域
   allowedMethods: #支持的請求類型
    - GET
    - POST
    - PUT
    - DELETE
  routes:
  # 對接商品goods微服務路由相關配置
  - id: changgou_goods_route
   uri: lb://changgou-goods
   predicates:
   - Path=/api/brand/**,/api/category/**
   filters:
   - StripPrefix=1
   - name: RequestRateLimiter # 請求數限流 名字不能隨便寫 ,使用默認的facatory
    args:
    # 用于限流的鍵的解析器的 Bean 對象的名字。它使用 SpEL 表達式根據#{@beanName}從 Spring 容器中獲取 Bean 對象。
    key-resolver: "#{@ipKeyResolver}"
    # 令牌桶每秒填充平均速率
    redis-rate-limiter.replenishRate: 1
    # 令牌桶總容量
    redis-rate-limiter.burstCapacity: 1
    # 上面配置,表示1秒內,允許 1個請求通過,令牌桶的填充速率也是1秒鐘添加1個令牌。
  # 對接用戶user微服務路由相關配置
  - id: changgou_user_route
   uri: lb://changgou-user
   predicates:
   - Path=/api/user/**,/api/address/**,/api/areas/**,/api/cities/**,/api/provinces/**
   filters:
   # user微服務真實請求中是沒有/api的,所以這里StripPrefix=1
   - StripPrefix=1
 # 微服務名稱
 application:
 name: changgou-gateway-web
 # Redis配置
 redis:
 # Redis數據庫索引(默認為0)
 database: 0
 # Redis服務器地址
 host: 8.131.66.136
 # Redis服務器連接端口
 port: 6379
 # Redis服務器連接密碼(默認為空)
 password: csp19990129

server:
 port: 8001
eureka:
 client:
 service-url:
  defaultZone: http://127.0.0.1:7001/eureka
 instance:
 prefer-ip-address: true
management:
 endpoint:
 gateway:
  enabled: true
 web:
  exposure:
  include: true

3.3 網關微服務主啟動類

/**
 * @Auther: csp1999
 * @Date: 2021/01/24/15:16
 * @Description: 用戶/前臺微服務網關啟動類
 */
@SpringBootApplication
@EnableEurekaClient
public class GatewayWebApplication {

 public static void main(String[] args) {
  SpringApplication.run(GatewayWebApplication.class, args);
 }

 /**
  * IP限流:由用戶請求的IP創(chuàng)建創(chuàng)建用戶唯一標識,進而根據IP進行限流操作
  *
  * @return
  */
 @Bean(name = "ipKeyResolver")
 public KeyResolver userKeyResolver() {
  return new KeyResolver() {
   @Override
   public Mono<String> resolve(ServerWebExchange exchange) {
    // 獲取遠程客戶端IP
    String hostName = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
    System.out.println("hostName:" + hostName);
    return Mono.just(hostName);
   }
  };
 }
}

3.4 用戶微服務編寫登錄代碼

/**
 * @Author: csp1999
 * @Description: User 的Controller
 * @Date 2021/1/14 0:18
 */
@RestController
@RequestMapping("/user")
@CrossOrigin
public class UserController {

 @Autowired
 private UserService userService;

	 /***
  * 修改User數據
  * @param user
  * @param id
  * @return
  */
 @PutMapping(value = "/{id}")
 public Result update(@RequestBody User user, @PathVariable String id) {
  	 ...
 }

 /***
  * 新增User數據
  * @param user
  * @return
  */
 @PostMapping
 public Result add(@RequestBody User user) {
  ...
 }

 /***
  * 根據ID查詢User數據
  * @param id
  * @return
  */
 @GetMapping("/{id}")
 public Result<User> findById(@PathVariable String id) {
  ...
 }

 /***
  * 查詢User全部數據
  * @return
  */
 @GetMapping
 public Result<List<User>> findAll() {
  ...
 }

 /***
  * 用戶登錄
  * @param username
  * @param password
  * @param response
  * @param request
  * @return
  */
 @RequestMapping("/login")
 public Result<User> login(String username, String password, HttpServletResponse response, HttpServletRequest request) {
  // 1.從數據庫中查詢用戶名對應的用戶的對象
  User user = userService.findById(username);
  if (user == null) {
   // 2.判斷用戶是否為空 為空返回數據
   return new Result<User>(false, StatusCode.LOGINERROR, "用戶名或密碼錯誤...");
  }

  // 3.如果不為空 判斷密碼是否正確 若正確 則登錄成功
  if (BCrypt.checkpw(password, user.getPassword())) {
   // 登錄成功,講用戶信息存入map
   Map<String, Object> info = new HashMap<String, Object>();
   info.put("role", "USER");
   info.put("success", "SUCCESS");
   info.put("username", username);

   // 3.1生成令牌
   String jwt = JwtUtil.createJWT(UUID.randomUUID().toString(), JSON.toJSONString(info), null);
   // 3.2設置jwt存入 cookie 中
   Cookie cookie = new Cookie("Authorization", jwt);
   response.addCookie(cookie);
   // 3.3設置jwt存入頭文件中
   response.setHeader("Authorization", jwt);

   return new Result<User>(true, StatusCode.OK, "登錄成功", jwt);
  } else {
   // 登錄失敗
   return new Result<User>(false, StatusCode.LOGINERROR, "用戶名或密碼錯誤");
  }
 }
}

到此這篇關于Spring Cloud Gateway 使用JWT工具類做用戶登錄校驗的示例代碼的文章就介紹到這了,更多相關Spring Cloud Gateway 用戶登錄校驗內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • SpringBoot傳給前端Long類型精度丟失的解決方案

    SpringBoot傳給前端Long類型精度丟失的解決方案

    最近在做項目的時候,遇到了一個Long類型傳給前端之后,接收到的數值不對的情況,我一開始以為是前端接收數據有問題,后來經過查找,了解到這是一個Long類型精度丟失問題,于是寫這篇文章記錄下來,也探究一下為什么會發(fā)生這種情況,需要的朋友可以參考下
    2025-03-03
  • SpringBoot中的WebSocketSession原理詳解

    SpringBoot中的WebSocketSession原理詳解

    這篇文章主要介紹了SpringBoot中的WebSocketSession原理詳解,傳統(tǒng)的?HTTP?協(xié)議是無法支持實時通信的,因為它是一種無狀態(tài)協(xié)議,每次請求都是獨立的,無法保持連接。為了解決這個問題,WebSocket?協(xié)議被引入,需要的朋友可以參考下
    2023-07-07
  • Spring中的@Qualifier注解詳解

    Spring中的@Qualifier注解詳解

    這篇文章主要介紹了Spring中的@Qualifier注解詳解,spring?@Autowire?的注解默認是按類型注入bean,本文將對其使用方法進行說明,需要的朋友可以參考下
    2023-11-11
  • 關于Java并發(fā)編程中線程間協(xié)作的兩種方式

    關于Java并發(fā)編程中線程間協(xié)作的兩種方式

    這篇文章主要介紹了關于Java并發(fā)編程中線程間協(xié)作的兩種方式,當隊列滿時,生產者需要等待隊列有空間才能繼續(xù)往里面放入商品,而在等待的期間內,生產者必須釋放對臨界資源的占用權,這是消費者模式,需要的朋友可以參考下
    2023-07-07
  • 一文總結RabbitMQ中的消息確認機制

    一文總結RabbitMQ中的消息確認機制

    RabbitMQ消息確認機制指的是在消息傳遞過程中,發(fā)送方發(fā)送消息后,接收方需要對消息進行確認,以確保消息被正確地接收和處理,本文為大家整理了RabbitMQ中的消息確認機制,需要的可以參考一下
    2023-06-06
  • java+vue3+el-tree實現(xiàn)樹形結構操作代碼

    java+vue3+el-tree實現(xiàn)樹形結構操作代碼

    基于springboot + vue3 elementPlus實現(xiàn)樹形結構數據的添加、刪除和頁面展示,本文通過示例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • Spring的CorsFilter會失效的原因及解決方法

    Spring的CorsFilter會失效的原因及解決方法

    眾所周知CorsFilter是Spring提供的跨域過濾器,我們可能會做以下的配置,基本上就是允許任何跨域請求,我利用Spring的CorsFilter做跨域操作但是出現(xiàn)報錯,接下來小編就給大家介紹一Spring的CorsFilter會失效的原因及解決方法,需要的朋友可以參考下
    2023-09-09
  • springboot使用redis注解做緩存的基本操作方式

    springboot使用redis注解做緩存的基本操作方式

    這篇文章主要介紹了springboot使用redis注解做緩存的基本用法,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Struts2實現(xiàn)文件上傳時顯示進度條功能

    Struts2實現(xiàn)文件上傳時顯示進度條功能

    這篇文章主要為大家詳細介紹了Struts2實現(xiàn)文件上傳時顯示進度條功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • gson對象序列化的示例

    gson對象序列化的示例

    本文介紹如何將Java對象序列化為Json文件,然后讀取該Json文件讀取回Java對象。在下面的示例中,我們創(chuàng)建了一個Student類。然后生成一個student.json文件,該文件將具有Student對象的json數據。
    2020-11-11

最新評論

綦江县| 安仁县| 依安县| 昆明市| 泸定县| 两当县| 黔江区| 杨浦区| 南部县| 会昌县| 丰城市| 绍兴县| 龙岩市| 永吉县| 永修县| 建宁县| 大同县| 忻城县| 成武县| 怀远县| 天镇县| 乳山市| 弥渡县| 木兰县| 许昌市| 宣城市| 双辽市| 麦盖提县| 溆浦县| 彭阳县| 黄山市| 山东省| 滨海县| 定西市| 留坝县| 潼关县| 原阳县| 夏津县| 迁西县| 涡阳县| 静海县|