1.前言
在上一篇文章的基础上我们学习搭建JWT的鉴权系统
1.0.JWT交互流程
上一篇:JWT使用
1.4.JWT交互流程
流程图:
步骤翻译:
• 1、用户登录
• 2、服务的认证,通过后根据secret生成token
• 3、将生成的token返回给用户
• 4、用户每次请求携带token
• 5、服务端利解读jwt签名,判断签名有效后,从Payload中获取用户信息
• 6、处理请求,返回响应结果
因为JWT签发的token中已经包含了用户的身份信息,并且每次请求都会携带,这样服务的就无需保存用户信息,甚至无需去数据库查询,就能知道用户身份,完全符合了Rest的无状态规范。
1.5.结合Zuul的鉴权流程
我们逐步演进系统架构设计。需要注意的是:secret是签名的关键,因此一定要保密,我们放到鉴权中心保存,其它任何服务中都不能获取secret。
在微服务架构中,我们可以把服务的鉴权操作放到网关中,将未通过鉴权的请求直接拦截,如图:
流程图解:
- 第一个流程:用户点击登录—>请求授权中心颁发jwt凭证
- 第二个流程:用户的每次请求都携带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:商品搜索服务,对外暴露商品搜索相关接口
结论:
- 项目的整体架构方式
- 搭建认证+授权中心
- 通过zuul进行权限过滤
3. 搭建父工程jwt-parent
3.1 创建项目
3.2 pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<modules>
<module>jwt-eureka</module>
<module>jwt-common</module>
<module>jwt-pojo</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.czxy</groupId>
<artifactId>jwt-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>jwt-parent</name>
<description>Demo project for Spring Boot</description>
<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>Greenwich.M3</spring-cloud.version>
<mybatis.starter.version>1.3.2</mybatis.starter.version>
<mapper.starter.version>1.2.3</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.16.22</lombok.version>
</properties>
<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>
<!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${joda-time.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</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>
添加一段配置,用来启动管理我们服务,写下文的时候突然发现没配,回来写上【捂脸】
<option name="configurationTypes">
<set>
<option value="SpringBootApplicationConfigurationType" />
</set>
</option>
4. 搭建Eureka注册中心
4.1 创建项目
注:网速好了用Spring脚手架,我用的maven模块搭的
4.2 pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.czxy</groupId>
<artifactId>jwt-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.czxy</groupId>
<artifactId>jwt-eureka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>jwt-eureka</name>
<description>Demo project for Spring Boot</description>
<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>
</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 测试
5.准备工作
5.1 创建jwt-common模块
5.1.1 创建项目
5.1.2 pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jwt-parent</artifactId>
<groupId>com.czxy</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jwt-common</artifactId>
<dependencies>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
5.1.3 加入工具类
jwt-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;
/**
* jwt工具类
*/
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);
//生成JWT
return builder.compact();
}
}
baseutil 这个主要是浏览器请求服务器,服务器接收请求作出的回执信息
/**
* 使用了lombok提供的@Data注解可以免写getset toString方法
* @Author ZhangLe
* @Date 2018/12/14 10:04
*/
@Data
public class BaseResult {
private Integer errno;//0成功,1失败
private String errmsg;//提示内容
private Object data;//返回的内容
public BaseResult(Integer errno, String errmsg,Object object) {
this.errno = errno;
this.errmsg = errmsg;
this.data=object;
}
}
5.2 创建jwt-pojo模块
5.2.1 创建项目
5.2.2 POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jwt-parent</artifactId>
<groupId>com.czxy</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jwt-pojo</artifactId>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
5.2.3 创建实体类
Goods商品实体类
/**
* 测试对象
*/
@Data
public class Goods {
private Integer skuid;
private String goodsName;
private Double price;
public Goods() {
}
public Goods(Integer skuid, String goodsName, Double price) {
this.skuid = skuid;
this.goodsName = goodsName;
this.price = price;
}
}
User实体类
/**
* @Author ZhangLe
* @Date 2018/12/17 17:30
*/
@Data
public class User {
private Integer id;
private String username;
private String password;
public User() {
}
public User(Integer id, String username, String password) {
this.id = id;
this.username = username;
this.password = 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="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.czxy</groupId>
<artifactId>jwt-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>goods-search</artifactId>
<packaging>jar</packaging>
<name>goods-search</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>com.czxy</groupId>
<artifactId>jwt-pojo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.czxy</groupId>
<artifactId>jwt-common</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: 8084
spring:
application:
name: goods-search
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true
ip-address: 127.0.0.1
instance-id: ${eureka.instance.ip-address}.${server.port}
lease-renewal-interval-in-seconds: 3
lease-expiration-duration-in-seconds: 10
6.5 功能实现
- 开启服务发现
2. 提供商品搜索功能
/**
* @Author ZhangLe
* @Date 2018/12/17 17:51
*/
@RestController
@RequestMapping("/search")
public class GoodsSearchController {
/**
* 我们使用伪造数据 知道是查出来的就行了 这里为了模拟Token
* @return
*/
@GetMapping
public BaseResult GoodsSearch(){
ArrayList<Goods> goods = new ArrayList<>();
goods.add(new Goods(1,"huawei",1.0));
goods.add(new Goods(2,"xiaomi",1.0));
goods.add(new Goods(3,"meizu",1.0));
BaseResult baseResult = new BaseResult(0,null,goods);
return baseResult;
}
}
6.6 功能测试
http://localhost:8084/search
7 搭建user-service服务
7.1 功能分析
- 1、提供用户操作相关的接口
7.2 搭建项目
还是推荐Spring脚手架搭建
7.3 pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.czxy</groupId>
<artifactId>jwt-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>user-service</artifactId>
<packaging>jar</packaging>
<name>user-service</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<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>
<dependency>
<groupId>com.czxy</groupId>
<artifactId>jwt-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.czxy</groupId>
<artifactId>jwt-pojo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</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: 8086
spring:
application:
name: user-service
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true
ip-address: 127.0.0.1
instance-id: ${eureka.instance.ip-address}.${server.port}
lease-renewal-interval-in-seconds: 3
lease-expiration-duration-in-seconds: 10
7.5 功能实现
- 提供用户新增接口
/**
* @Author ZhangLe
* @Date 2018/12/17 18:45
*/
@RestController
@RequestMapping("user")
public class UserController {
@PostMapping
public BaseResult saveUser(User user){
System.out.println("新增用户"+user);
return new BaseResult(0,"success",null);
}
}
7.6 功能测试
http://localhost:8086/user
8. 授权中心jwt-auth
授权中心的主要职责:
• 用户鉴权:
– 接收用户的登录请求,通过用户中心的接口进行校验,通过后生成JWT
– 使用私钥生成JWT并返回
• 服务鉴权:微服务间的调用不经过Zuul,会有风险,需要鉴权中心进行认证
– 原理与用户鉴权类似,但逻辑稍微复杂一些(此处我们不做实现)
因为生成jwt,解析jwt这样的行为以后在其它微服务中也会用到,因此我们会抽取成工具。我们把鉴权中心进行聚合,一个工具module,一个提供服务的module
8.1 创建授权中心
8.2 pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.czxy</groupId>
<artifactId>jwt-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>jwt-auth</artifactId>
<packaging>jar</packaging>
<name>jwt-auth</name>
<description>Demo project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.czxy</groupId>
<artifactId>jwt-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.czxy</groupId>
<artifactId>jwt-pojo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</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: 8082
spring:
application:
name: jwt-auth
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true
ip-address: 127.0.0.1
instance-id: ${eureka.instance.ip-address}.${server.port}
lease-renewal-interval-in-seconds: 3
lease-expiration-duration-in-seconds: 10
8.4 功能实现
- 提供登录接口
8.5 功能测试
http://localhost:8082/login?username=admin&password=admin
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="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>jwt-parent</artifactId>
<groupId>com.czxy</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jwt-zuul</artifactId>
<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-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</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>
9.4 yml
server:
port: 10010
spring:
application:
name: jwt-zuul
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
instance:
prefer-ip-address: true
ip-address: 127.0.0.1
instance-id: ${eureka.instance.ip-address}.${server.port}
lease-renewal-interval-in-seconds: 3
lease-expiration-duration-in-seconds: 10
ribbon:
ConnectTimeout: 300
ReadTimeout: 1000
OkToRetryOnAllOperations: true
MaxAutoRetriesNextServer: 2
MaxAutoRetries: 1
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 6000
9.5 功能实现
- 配置服务发现和开启zuul网关功能
/**
* @Author ZhangLe
* @Date 2018/12/18 8:34
*/
@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
public class UserZuulApplication {
public static void main(String[] args) {
SpringApplication.run(UserZuulApplication.class,args);
}
}
- 编写鉴权过滤器
- 继承网关监听器
ZuulFilter
重写父类方法
重写这个方法内容
这段代码建议仔细看看run()
方法
package com.czxy.config;
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;
/**
* @Author ZhangLe
* @Date 2018/12/18 8:37
*/
@Component
public class JWTFilter extends ZuulFilter {
@Override
public String filterType() {
System.out.println("前置过滤器");
return "pre";
}
@Override
public int filterOrder() {
System.out.println("优先级别,数字越小,优先级越高");
return 0;
}
@Override
public boolean shouldFilter() {
System.out.println("是否执行过滤器,true,执行");
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext currentContext = RequestContext.getCurrentContext();
//获取header
HttpServletRequest request = currentContext.getRequest();
//获取请求的url
String url = request.getRequestURL().toString();
if (url.indexOf("/login")>0 || url.indexOf("/search") > 0){
System.out.println("登录");
return null;
}
String key = "";
if (url.indexOf("user-service") != -1){
key = "user";
String token = request.getHeader("authorizztion");
if (token != null){
Claims claims = JWTUtil.parseToken(token, key);
if (claims != null){
currentContext.addZuulRequestHeader("authorizztion",token);
return null;
}
}
}
currentContext.setSendZuulResponse(false);//终止运行
currentContext.setResponseStatusCode(401);
currentContext.setResponseBody("{'flag':false,'message':'未登录'}");
currentContext.getResponse().setContentType("text/html;charset=UTF-8");
return null;
}
}
9.6 功能测试
-
商品搜索
http://localhost:10010/goods-search/search
-
用户新增(未登录)
http://localhost:10010/user-service/user
未携带token
-
用户登录
-
http://localhost:10010/jwt-auth/login?username=admin&password=admin
-
携带token,进行用户新增
-
http://localhost:10010/user-service/user
注:必须先登录,获取到token才能用户新增
token
eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjEsImV4cCI6MTU0NTA5NzM2M30.ouywUb_0KG4H132AcjPArSHkLXos1ceafGiNMpgdSdo
写了token,Authorizztion
大小写无所谓
番外
网关执行流程
用户新增
祝你幸福
送你一首歌《直到遇见了你我只喜欢你》陈柯宇
我去商场偶然听见,记住了高潮部分歌词 然后搜了出来,第一次听
附图:中国地图(看看以后自己会去哪,下个月写点面试经验,给以后的自己看)