StringCloud_JWT(鉴权)

编程入门 行业动态 更新时间:2024-10-23 14:23:50

StringCloud_JWT(<a href=https://www.elefans.com/category/jswz/34/1385747.html style=鉴权)"/>

StringCloud_JWT(鉴权)

文章目录

  • 1. 为什么要学习JWT?
    • 1.1.简介
    • 1.2.数据格式
    • 1.3. JWT详解
      • 1.3.1 base64编码原理(了解)
      • 1.3.2 jwt测试-JwtUtil的使用
    • 1.4. JWT交互流程
    • 1.5.结合Zuul的鉴权流程
  • 2. 项目整体架构
  • 3. 搭建父工程jwt-parent
    • 3.1 创建项目
    • 3.2 pom
  • 4. 搭建Eureka注册中心
    • 4.1 创建项目
    • 4.2 pom
    • 4.3 yml配置
    • 4.4 开启EuerkaServer注解
    • 4.5 测试
  • 5.准备工作
    • 5.1 创建jwt-common模块
      • 5.1.1 创建项目
      • 5.1.2 pom
      • 5.1.3 加入工具类
    • 5.2 创建jwt-pojo模块
      • 5.2.1 创建项目
      • 5.2.2 POM
      • 5.2.3 创建实体类
  • 6. 搭建goods-search
    • 6.1 功能分析
    • 6.2 创建项目
    • 6.3 pom
    • 6.4 yml配置
    • 6.5 功能实现
    • 6.6 功能测试
  • 7 搭建user-service服务
    • 7.1 功能分析
    • 7.2 搭建项目
    • 7.3 pom
    • 7.4 yml
    • 7.5 功能实现
    • 7.6 功能测试
  • 8. 授权中心jwt-auth
    • 8.1 创建授权中心
    • 8.2 pom
    • 8.3 yml
    • 8.4 功能实现
    • 8.5 功能测试
  • 9. Zuul网关jwt-zuul
    • 9.1 功能分析
    • 9.2 搭建jwt-zuul项目
    • 9.3 pom
    • 9.5 功能实现
    • 9.6 功能测试

1. 为什么要学习JWT?

1.1.简介

JWT,全称是Json Web Token, 是JSON风格轻量级的授权和身份认证规范,可实现无状态、分布式的Web应用授权;它是分布式服务权限控制的标准解决方案!

  • 官网:

    GitHub上jwt的java客户端:

什么是token:.html

1.2.数据格式

普通的token:32位UUID

JWT的token:至少64位

JWT的token包含三部分数据:

  • Header:头部,通常头部有两部分信息:

    • 声明类型type,这里是JWT(type=jwt)

    • 加密算法,自定义(rs256/base64/hs256)

      我们会对头部进行base64加密(可解密),得到第一部分数据

  • Payload:载荷,就是有效数据,一般包含下面信息:

  • 用户身份信息-userid,username(注意,这里因为采用base64加密,可解密,因此不要存放敏感信息)

  • 注册声明:如token的签发时间,过期时间,签发人等

    这部分也会采用base64加密,得到第二部分数据

  • Signature:base64加密,签名,是整个数据的认证信息。一般根据前两步的数据,再加上服务的的密钥(secret,盐)(不要泄漏,最好周期性更换),通过加密算法生成。用于验证整个数据完整和可靠性

结论:

1 jwt的一个有规则的token

2 它有三部分组成:Header.payload.signature,每部分都是通过base64加密而成的

3 jwt前两个部分都是可以解密的

1.3. JWT详解

1.3.1 base64编码原理(了解)

Base64编码之所以称为Base64,是因为其使用64个字符来对任意数据进行编码,同理有Base32、Base16编码。标准Base64编码使用的64个字符如下:

这64个字符是各种字符编码(比如ASCII码)所使用字符的子集,并可打印。唯一有点特殊的是最后两个字符。

Base64本质上是一种将二进制数据转成文本数据的方案。对于非二进制数据,是先将其转换成二进制形式,然后每连续6比特(2的6次方=64)计算其十进制值,根据该值在上面的索引表中找到对应的字符,最终得到一个文本字符串。假设我们对Hello!进行Base64编码,按照ASCII表,其转换过程如下图所示:

可知Hello!的Base64编码结果为SGVsbG8h,原始字符串长度为6个字符串,编码后长度为8个字符,每3个原始字符经编码成4个字符。

但要注意,Base64编码是每3个原始字符编码成4个字符,如果原始字符串长度不能被3整除,怎么办?使用0来补充原始字符串。

以Hello!!为例,其转换过程为:

Hello!! Base64编码的结果为 SGVsbG8hIQAA 。最后2个零值只是为了Base64编码而补充的,在原始字符中并没有对应的字符,那么Base64编码结果中的最后两个字符 AA 实际不带有效信息,所以需要特殊处理,以免解码错误。

标准Base64编码通常用 = 字符来替换最后的 A,即编码结果为 SGVsbG8hIQ==。因为 = 字符并不在Base64编码索引表中,其意义在于结束符号,在Base64解码时遇到 = 时即可知道一个Base64编码字符串结束。

如果Base64编码字符串不会相互拼接再传输,那么最后的 = 也可以省略,解码时如果发现Base64编码字符串长度不能被4整除,则先补充 = 字符,再解码即可。

解码是对编码的逆向操作,但注意一点:对于最后的两个 = 字符,转换成两个A 字符,再转成对应的两个6比特二进制0值,接着转成原始字符之前,需要将最后的两个6比特二进制0值丢弃,因为它们实际上不携带有效信息。

总结:

1、base64的编码/加密原理

答:原理:将键盘输入的字符用base64编码表示

过程:将键盘输入字符的ascii码值,转成的对应8位二进制,将该二进制6个一组拆分,并计算拆分之后的十进制值,找出十进制值在base64编码表中对应的字母,即完成base64加密

1.3.2 jwt测试-JwtUtil的使用

  1. 导入jar包
 <properties><jjwt.version>0.7.0</jjwt.version><joda-time.version>2.9.6</joda-time.version></properties><dependencies><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>${jjwt.version}</version></dependency><!--  --><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>${joda-time.version}</version></dependency></dependencies>
  1. 导入JwtUtil
package com.czxy.util;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.joda.time.DateTime;import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;/*** @Description: token工具类*/
public class JWTUtil {/*** 获取token中的参数** @param token* @return*/public static Claims parseToken(String token,String key) {if ("".equals(token)) {return null;}try {return Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(key)).parseClaimsJws(token).getBody();} catch (Exception ex) {return null;}}/*** 生成token** @param userId* @return*/public static String createToken(Integer userId,String key, int expireMinutes) {SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;long nowMillis = System.currentTimeMillis();//生成签名密钥byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(key);Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());//添加构成JWT的参数JwtBuilder builder = Jwts.builder()
//                .setHeaderParam("type", "JWT")
//                .setSubject(userId.toString()).claim("userId", userId) // 设置载荷信息.setExpiration(DateTime.now().plusMinutes(expireMinutes).toDate())// 设置超时时间.signWith(signatureAlgorithm, signingKey);//生成JWTreturn builder.compact();}
}/**
解密
*/
public static void main(String[] args) {String token = JWTUtil.createToken(1, "zhangsan","admin", 30);System.out.println(token);Claims claims = JWTUtil.parseToken(token, "admin");System.out.println();}
  1. 编码测试

结论:

  1. jwt是采用base64加密/编码的

1.4. JWT交互流程

流程图:

步骤翻译:

• 1、用户登录

• 2、服务的认证,通过后根据secret生成token

• 3、将生成的token返回给用户

• 4、用户每次请求携带token

• 5、服务端利解读jwt签名,判断签名有效后,从Payload中获取用户信息

• 6、处理请求,返回响应结果

因为JWT签发的token中已经包含了用户的身份信息,并且每次请求都会携带,这样服务的就无需保存用户信息,甚至无需去数据库查询,就能知道用户身份,完全符合了Rest的无状态规范。

1.5.结合Zuul的鉴权流程

我们逐步演进系统架构设计。需要注意的是:secret是签名的关键,因此一定要保密,我们放到鉴权中心保存,其它任何服务中都不能获取secret。

在微服务架构中,我们可以把服务的鉴权操作放到网关中,将未通过鉴权的请求直接拦截,如图:

流程图解:

  1. 第一个流程:用户点击登录—>请求授权中心颁发jwt凭证
  2. 第二个流程:用户的每次请求都携带jwt凭证—>zuul判断jwt是否正确

• 1、用户请求登录

• 2、Zuul将请求转发到授权中心,请求授权

• 3、授权中心校验完成,颁发JWT凭证

• 4、客户端请求其它功能,携带JWT

• 5、Zuul将jwt交给授权中心校验,通过后放行

• 6、用户请求到达微服务

• 7、微服务将jwt交给鉴权中心,鉴权同时解析用户信息

• 8、鉴权中心返回用户数据给微服务

• 9、微服务处理请求,返回响应

2. 项目整体架构

  • jwt-parent:统一jar包版本控制
  • jwt-eureka:eureka注册中心
  • user-service:用户服务,对外暴露用户操作相关接口,如新增用户等
  • jwt-auth:认证中心
  • jwt-pojo:实体类存放位置
  • jwt-common:工具类、常量类等存放的位置
  • goods-search:商品搜索服务,对外暴露商品搜索相关接口

结论:

  1. 项目的整体架构方式
  2. 搭建认证+授权中心
  3. 通过zuul进行权限过滤

3. 搭建父工程jwt-parent

3.1 创建项目

3.2 pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".0.0" xmlns:xsi=""xsi:schemaLocation=".0.0 .0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.czxy</groupId><artifactId>jwt-parent01</artifactId><packaging>pom</packaging><version>0.0.1-SNAPSHOT</version><modules><module>jwt-pojo01</module><module>jwt-commom01</module></modules><name>jwt-parent01</name><description>Demo project for Spring Boot</description><!-- 父工程中只是统一版本依赖,但是不实际导入jar包 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.2.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><spring-cloud.version>Hoxton.RELEASE</spring-cloud.version><mybatis.starter.version>1.3.2</mybatis.starter.version><mapper.starter.version>2.0.2</mapper.starter.version><druid.starter.version>1.1.9</druid.starter.version><mysql.version>5.1.32</mysql.version><pageHelper.starter.version>1.2.3</pageHelper.starter.version><jjwt.version>0.7.0</jjwt.version><joda-time.version>2.9.6</joda-time.version><lombok.version>1.18.10</lombok.version></properties><!-- dependencyManagement这个标签一般用在父项目中,他不是导入jar包的标签,只是用来限定jar包版本的标签然后子项目依赖当前父项目,在子项目中导入需要的jar包坐标子项目无需填入版本号,完全由父项目控制--><dependencyManagement><dependencies><!-- springCloud --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><!-- mybatis启动器 --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.starter.version}</version></dependency><!-- 通用Mapper启动器 --><dependency><groupId>tk.mybatis</groupId><artifactId>mapper-spring-boot-starter</artifactId><version>${mapper.starter.version}</version></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>${pageHelper.starter.version}</version></dependency><!-- druid启动器 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>${druid.starter.version}</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>${jjwt.version}</version></dependency><!--  --><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>${joda-time.version}</version></dependency><!--get set--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version></dependency></dependencies></dependencyManagement><!-- 配置Spring私服: 提高下载速度--><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>;/url><snapshots><enabled>false</enabled></snapshots></repository></repositories><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

4. 搭建Eureka注册中心

4.1 创建项目

4.2 pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".0.0" xmlns:xsi=""xsi:schemaLocation=".0.0 .0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.czxy</groupId><artifactId>jwt-eureka01</artifactId><version>0.0.1-SNAPSHOT</version><name>jwt-eureka01</name><description>Demo project for Spring Boot</description><parent><groupId>com.czxy</groupId><artifactId>jwt-parent01</artifactId><version>0.0.1-SNAPSHOT</version></parent><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

父工程:

4.3 yml配置

server:port: 10086 #eureka端口号spring:application:name: eureka-server #eureka服务的名字eureka:server:enable-self-preservation: true # Eureka自我保护机制,true打开/false禁用,默认打开状态,建议生产环境打开此配置。eviction-interval-timer-in-ms: 5000 # 修改检查失效服务的时间client:fetch-registry: true # 定期的更新客户端的服务清单,以保证服务访问的正确性register-with-eureka: true # 是否将自己注册为服务service-url:defaultZone: http://127.0.0.1:${server.port}/eureka # eureka服务的开放地址

4.4 开启EuerkaServer注解

4.5 测试

5.准备工作

5.1 创建jwt-common模块

5.1.1 创建项目

5.1.2 pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".0.0"xmlns:xsi=""xsi:schemaLocation=".0.0 .0.0.xsd"><modelVersion>4.0.0</modelVersion><artifactId>jwt-commom01</artifactId><parent><artifactId>jwt-parent01</artifactId><groupId>com.czxy</groupId><version>0.0.1-SNAPSHOT</version></parent><dependencies><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency><!--  --><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>
</project>

5.1.3 加入工具类

5.2 创建jwt-pojo模块

5.2.1 创建项目

5.2.2 POM

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".0.0"xmlns:xsi=""xsi:schemaLocation=".0.0 .0.0.xsd"><modelVersion>4.0.0</modelVersion><artifactId>jwt-pojo01</artifactId><parent><artifactId>jwt-parent01</artifactId><groupId>com.czxy</groupId><version>0.0.1-SNAPSHOT</version></parent><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>
</project>

5.2.3 创建实体类

Goods商品实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Goods {private Integer skuid;private String goodsName;private Double price;
}

User实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private Integer id;private String username;private String password;
}

6. 搭建goods-search

6.1 功能分析

1、用户未登陆状态,可以搜索商品信息

2、goods-search为商品搜索服务,接收用户页面搜索请求

实现步骤:

1、pojo

2、controller

4、service

5、dao

6.2 创建项目

6.3 pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".0.0" xmlns:xsi=""xsi:schemaLocation=".0.0 .0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.czxy</groupId><artifactId>goods-search01</artifactId><version>0.0.1-SNAPSHOT</version><name>goods-search01</name><description>Demo project for Spring Boot</description><parent><groupId>com.czxy</groupId><artifactId>jwt-parent01</artifactId><version>0.0.1-SNAPSHOT</version></parent><dependencies><dependency><groupId>com.czxy</groupId><artifactId>jwt-pojo01</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>com.czxy</groupId><artifactId>jwt-commom01</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

6.4 yml配置

server:port: 8091
spring:application:name: goods-search
eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eurekainstance:prefer-ip-address: trueip-address: 127.0.0.1instance-id: ${eureka.instance.ip-address}.${server.port}lease-renewal-interval-in-seconds: 3lease-expiration-duration-in-seconds: 10

6.5 功能实现

  1. 开启服务发现
  2. 提供商品搜索功能

6.6 功能测试

7 搭建user-service服务

7.1 功能分析

  • 1、提供用户操作相关的接口

7.2 搭建项目

7.3 pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".0.0" xmlns:xsi=""xsi:schemaLocation=".0.0 .0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.czxy</groupId><artifactId>user-service01</artifactId><version>0.0.1-SNAPSHOT</version><name>user-service01</name><description>Demo project for Spring Boot</description><parent><groupId>com.czxy</groupId><artifactId>jwt-parent01</artifactId><version>0.0.1-SNAPSHOT</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.czxy</groupId><artifactId>jwt-commom01</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>com.czxy</groupId><artifactId>jwt-pojo01</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

7.4 yml

server:port: 8090
spring:application:name: user-service
eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eurekainstance:prefer-ip-address: trueip-address: 127.0.0.1instance-id: ${eureka.instance.ip-address}.${server.port}lease-renewal-interval-in-seconds: 3lease-expiration-duration-in-seconds: 10

7.5 功能实现

  • 提供用户新增接口

7.6 功能测试

8. 授权中心jwt-auth

授权中心的主要职责:

  • 用户鉴权:
    • 接收用户的登录请求,通过用户中心的接口进行校验,通过后生成JWT
    • 使用私钥生成JWT并返回
  • 服务鉴权:微服务间的调用不经过Zuul,会有风险,需要鉴权中心进行认证
    • 原理与用户鉴权类似,但逻辑稍微复杂一些(此处我们不做实现)

因为生成jwt,解析jwt这样的行为以后在其它微服务中也会用到,因此我们会抽取成工具。我们把鉴权中心进行聚合,一个工具module,一个提供服务的module

8.1 创建授权中心

8.2 pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".0.0" xmlns:xsi=""xsi:schemaLocation=".0.0 .0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.czxy</groupId><artifactId>jwt-auth01</artifactId><version>0.0.1-SNAPSHOT</version><name>jwt-auth01</name><description>Demo project for Spring Boot</description><parent><groupId>com.czxy</groupId><artifactId>jwt-parent01</artifactId><version>0.0.1-SNAPSHOT</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.czxy</groupId><artifactId>jwt-commom01</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>com.czxy</groupId><artifactId>jwt-pojo01</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

8.3 yml

server:port: 8080
spring:application:name: jwt-auth
eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eurekainstance:prefer-ip-address: trueip-address: 127.0.0.1instance-id: ${eureka.instance.ip-address}.${server.port}lease-renewal-interval-in-seconds: 3lease-expiration-duration-in-seconds: 10

8.4 功能实现

  • 提供登录接口

8.5 功能测试

9. Zuul网关jwt-zuul

9.1 功能分析

  • 1、对所有请求进行过滤
  • 2、如果用户发起的是登录操作或者是商品搜索操作,放行
  • 3、如果用户发起的是对user-service服务的操作,获取并解析token,如果token存在且有效,放行;否则响应错误页面

9.2 搭建jwt-zuul项目

9.3 pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".0.0" xmlns:xsi=""xsi:schemaLocation=".0.0 .0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.czxy</groupId><artifactId>jwt-zuul01</artifactId><version>0.0.1-SNAPSHOT</version><name>jwt-zuul01</name><description>Demo project for Spring Boot</description><parent><artifactId>jwt-parent01</artifactId><groupId>com.czxy</groupId><version>0.0.1-SNAPSHOT</version></parent><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-zuul</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>com.czxy</groupId><artifactId>jwt-commom01</artifactId><version>0.0.1-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

9.5 功能实现

  • 配置服务发现和开启zuul网关功能
  • 编写鉴权过滤器
package com.czxy.filter;import com.czxy.util.JWTUtil;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import io.jsonwebtoken.Claims;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;@Component
public class JWTFilter extends ZuulFilter {@Overridepublic String filterType() {return "pre";}@Overridepublic int filterOrder() {return 0;}@Overridepublic boolean shouldFilter() {return true;}/*** 核心业务* 拦截服务或者拦截请求* 1 jwt-auth  放行* 2 goods-search 拦截* 3 user-service 拦截* 通过zuul请求具体服务的时候,url中肯定有服务名字* 如何拦截?* 答:判断用户是否携带了token,同时token能否被解析通过*/@Overridepublic Object run() throws ZuulException {//1获取请求路径RequestContext ctx = RequestContext.getCurrentContext();HttpServletRequest request = ctx.getRequest();StringBuffer url = request.getRequestURL();/*** jwt-auth/login 放行* goods-search/search 拦截* user-service/user 拦截*///3判断登录放行路径if (url.toString().contains("jwt-auth/login")){System.out.println("无需登录,直接放行");return null;}// 4 需要判断用户是否登录// 5 获取用户的token信息: 页面传递的token的名字/key 很固定,就叫authorization,而且这个信息一定放在request的请求头header中String token = request.getHeader("authorization");// 6判断是否为空if (token!=null&&(!"".equals(token.trim()))){//7 解析token-能够被jwt解析,不能解析的话,也是无效的token或者超时的tokenClaims claims = JWTUtil.parseToken(token, "admin");//8 判断解析是否成功if (claims!=null){// 将token续传到后面服务ctx.addZuulRequestHeader("authorization",token);//成功 放行return null;}}//报错--权限效验失败ctx.setSendZuulResponse(false);ctx.setResponseStatusCode(401);ctx.setResponseBody("{'msg':'效验失败'}");ctx.getResponse().setContentType("text/html;charset=utf-8");return null;}
}

9.6 功能测试

  • 商品搜索

  • 用户新增(未登录)

  • 用户登录

  • 携带token,进行用户新增

更多推荐

StringCloud_JWT(鉴权)

本文发布于:2023-07-27 22:08:24,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1225201.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:StringCloud_JWT   鉴权

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!