鉴权系统搭建(JWT)

1.前言

在上一篇文章的基础上我们学习搭建JWT的鉴权系统
1.0.JWT交互流程
上一篇:JWT使用
1.4.JWT交互流程
流程图:
鉴权系统搭建(JWT)_第1张图片

步骤翻译:

• 1、用户登录

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

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

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

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

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

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

1.5.结合Zuul的鉴权流程

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

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

鉴权系统搭建(JWT)_第2张图片
流程图解:

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

• 1、用户请求登录

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

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

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

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

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

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

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

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

2. 项目整体架构

以下项目要搭建出这几个模块,有的话直接搭建认证模块

鉴权系统搭建(JWT)_第3张图片

  • 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 创建项目

鉴权系统搭建(JWT)_第4张图片

3.2 pom

 
<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.0modelVersion>
    <modules>
        <module>jwt-eurekamodule>
        <module>jwt-commonmodule>
        <module>jwt-pojomodule>
    modules>
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.1.1.RELEASEversion>
        <relativePath/> 
    parent>
    <groupId>com.czxygroupId>
    <artifactId>jwt-parentartifactId>
    <version>0.0.1-SNAPSHOTversion>
    <packaging>pompackaging>
    <name>jwt-parentname>
    <description>Demo project for Spring Bootdescription>

    <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
        <java.version>1.8java.version>
        <spring-cloud.version>Greenwich.M3spring-cloud.version>
        <mybatis.starter.version>1.3.2mybatis.starter.version>
        <mapper.starter.version>1.2.3mapper.starter.version>
        <druid.starter.version>1.1.9druid.starter.version>
        <mysql.version>5.1.32mysql.version>
        <pageHelper.starter.version>1.2.3pageHelper.starter.version>
        <jjwt.version>0.7.0jjwt.version>
        <joda-time.version>2.9.6joda-time.version>
        <lombok.version>1.16.22lombok.version>
    properties>


    <dependencyManagement>
        <dependencies>
            
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-dependenciesartifactId>
                <version>${spring-cloud.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
            
            <dependency>
                <groupId>org.mybatis.spring.bootgroupId>
                <artifactId>mybatis-spring-boot-starterartifactId>
                <version>${mybatis.starter.version}version>
            dependency>
            
            <dependency>
                <groupId>tk.mybatisgroupId>
                <artifactId>mapper-spring-boot-starterartifactId>
                <version>${mapper.starter.version}version>
            dependency>
            <dependency>
                <groupId>com.github.pagehelpergroupId>
                <artifactId>pagehelper-spring-boot-starterartifactId>
                <version>${pageHelper.starter.version}version>
            dependency>
            
            <dependency>
                <groupId>com.alibabagroupId>
                <artifactId>druid-spring-boot-starterartifactId>
                <version>${druid.starter.version}version>
            dependency>
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>${mysql.version}version>
            dependency>
            <dependency>
                <groupId>io.jsonwebtokengroupId>
                <artifactId>jjwtartifactId>
                <version>${jjwt.version}version>
            dependency>
            
            <dependency>
                <groupId>joda-timegroupId>
                <artifactId>joda-timeartifactId>
                <version>${joda-time.version}version>
            dependency>

            <dependency>
                <groupId>org.projectlombokgroupId>
                <artifactId>lombokartifactId>
                <version>${lombok.version}version>
                <scope>providedscope>
            dependency>
        dependencies>
    dependencyManagement>



    <repositories>
        <repository>
            <id>spring-milestonesid>
            <name>Spring Milestonesname>
            <url>https://repo.spring.io/milestoneurl>
            <snapshots>
                <enabled>falseenabled>
            snapshots>
        repository>
    repositories>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>


project>

添加一段配置,用来启动管理我们服务,写下文的时候突然发现没配,回来写上【捂脸】

    <option name="configurationTypes">
      <set>
        <option value="SpringBootApplicationConfigurationType" />
      set>
    option>

鉴权系统搭建(JWT)_第5张图片

4. 搭建Eureka注册中心

4.1 创建项目

注:网速好了用Spring脚手架,我用的maven模块搭的
鉴权系统搭建(JWT)_第6张图片

4.2 pom


<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.0modelVersion>
    <parent>
        <groupId>com.czxygroupId>
        <artifactId>jwt-parentartifactId>
        <version>0.0.1-SNAPSHOTversion>
    parent>
    <groupId>com.czxygroupId>
    <artifactId>jwt-eurekaartifactId>
    <version>0.0.1-SNAPSHOTversion>
    <packaging>jarpackaging>
    <name>jwt-eurekaname>
    <description>Demo project for Spring Bootdescription>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            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 测试

鉴权系统搭建(JWT)_第7张图片

5.准备工作

5.1 创建jwt-common模块

5.1.1 创建项目

鉴权系统搭建(JWT)_第8张图片

5.1.2 pom

 
<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-parentartifactId>
        <groupId>com.czxygroupId>
        <version>0.0.1-SNAPSHOTversion>
    parent>
    <modelVersion>4.0.0modelVersion>

    <artifactId>jwt-commonartifactId>

    <dependencies>
        <dependency>
            <groupId>io.jsonwebtokengroupId>
            <artifactId>jjwtartifactId>
        dependency>
        
        <dependency>
            <groupId>joda-timegroupId>
            <artifactId>joda-timeartifactId>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <scope>providedscope>
        dependency>

    dependencies>
project>

5.1.3 加入工具类

鉴权系统搭建(JWT)_第9张图片

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 创建项目

鉴权系统搭建(JWT)_第10张图片

5.2.2 POM

 
<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-parentartifactId>
        <groupId>com.czxygroupId>
        <version>0.0.1-SNAPSHOTversion>
    parent>
    <modelVersion>4.0.0modelVersion>

    <artifactId>jwt-pojoartifactId>

    <dependencies>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <scope>providedscope>
        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 创建项目

鉴权系统搭建(JWT)_第11张图片

6.3 pom


<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.0modelVersion>
    <parent>
        <groupId>com.czxygroupId>
        <artifactId>jwt-parentartifactId>
        <version>0.0.1-SNAPSHOTversion>
    parent>
    <artifactId>goods-searchartifactId>
    <packaging>jarpackaging>
    <name>goods-searchname>
    <description>Demo project for Spring Bootdescription>


    <dependencies>
        <dependency>
            <groupId>com.czxygroupId>
            <artifactId>jwt-pojoartifactId>
            <version>0.0.1-SNAPSHOTversion>
        dependency>

        <dependency>
            <groupId>com.czxygroupId>
            <artifactId>jwt-commonartifactId>
            <version>0.0.1-SNAPSHOTversion>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            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 功能实现

  1. 开启服务发现

鉴权系统搭建(JWT)_第12张图片
2. 提供商品搜索功能
鉴权系统搭建(JWT)_第13张图片

 
/**
 * @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
鉴权系统搭建(JWT)_第14张图片

7 搭建user-service服务

7.1 功能分析

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

7.2 搭建项目

还是推荐Spring脚手架搭建
鉴权系统搭建(JWT)_第15张图片

7.3 pom


<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.0modelVersion>
    <parent>
        <groupId>com.czxygroupId>
        <artifactId>jwt-parentartifactId>
        <version>0.0.1-SNAPSHOTversion>
    parent>
    <artifactId>user-serviceartifactId>
    <packaging>jarpackaging>
    <name>user-servicename>
    <description>Demo project for Spring Bootdescription>

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>com.czxygroupId>
            <artifactId>jwt-commonartifactId>
            <version>0.0.1-SNAPSHOTversion>
        dependency>
        <dependency>
            <groupId>com.czxygroupId>
            <artifactId>jwt-pojoartifactId>
            <version>0.0.1-SNAPSHOTversion>
        dependency>
    dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            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 功能实现

  • 提供用户新增接口
    鉴权系统搭建(JWT)_第16张图片
/**
 * @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鉴权系统搭建(JWT)_第17张图片

8. 授权中心jwt-auth

授权中心的主要职责:

• 用户鉴权:

– 接收用户的登录请求,通过用户中心的接口进行校验,通过后生成JWT

– 使用私钥生成JWT并返回

• 服务鉴权:微服务间的调用不经过Zuul,会有风险,需要鉴权中心进行认证

– 原理与用户鉴权类似,但逻辑稍微复杂一些(此处我们不做实现)

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

8.1 创建授权中心

鉴权系统搭建(JWT)_第18张图片

8.2 pom


<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.0modelVersion>
    <parent>
        <groupId>com.czxygroupId>
        <artifactId>jwt-parentartifactId>
        <version>0.0.1-SNAPSHOTversion>
    parent>
    <artifactId>jwt-authartifactId>
    <packaging>jarpackaging>
    <name>jwt-authname>
    <description>Demo project for Spring Bootdescription>

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>com.czxygroupId>
            <artifactId>jwt-commonartifactId>
            <version>0.0.1-SNAPSHOTversion>
        dependency>
        <dependency>
            <groupId>com.czxygroupId>
            <artifactId>jwt-pojoartifactId>
            <version>0.0.1-SNAPSHOTversion>
        dependency>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            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 功能实现

  • 提供登录接口
    鉴权系统搭建(JWT)_第19张图片

8.5 功能测试

http://localhost:8082/login?username=admin&password=admin

鉴权系统搭建(JWT)_第20张图片

9. Zuul网关jwt-zuul

9.1 功能分析

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

9.2 搭建jwt-zuul项目

鉴权系统搭建(JWT)_第21张图片

9.3 pom


<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-parentartifactId>
        <groupId>com.czxygroupId>
        <version>0.0.1-SNAPSHOTversion>
    parent>
    <modelVersion>4.0.0modelVersion>

    <artifactId>jwt-zuulartifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-zuulartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
        dependency>
        <dependency>
            <groupId>com.czxygroupId>
            <artifactId>jwt-commonartifactId>
            <version>0.0.1-SNAPSHOTversion>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            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网关功能
    鉴权系统搭建(JWT)_第22张图片
/**
 * @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重写父类方法
    鉴权系统搭建(JWT)_第23张图片
    重写这个方法内容鉴权系统搭建(JWT)_第24张图片

这段代码建议仔细看看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鉴权系统搭建(JWT)_第25张图片

  • 用户新增(未登录)

http://localhost:10010/user-service/user

未携带token
鉴权系统搭建(JWT)_第26张图片

  • 用户登录

  • http://localhost:10010/jwt-auth/login?username=admin&password=admin
    鉴权系统搭建(JWT)_第27张图片

  • 携带token,进行用户新增

  • http://localhost:10010/user-service/user
    注:必须先登录,获取到token才能用户新增

token

eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjEsImV4cCI6MTU0NTA5NzM2M30.ouywUb_0KG4H132AcjPArSHkLXos1ceafGiNMpgdSdo

写了token,Authorizztion大小写无所谓
鉴权系统搭建(JWT)_第28张图片
番外
网关执行流程
鉴权系统搭建(JWT)_第29张图片
用户新增
鉴权系统搭建(JWT)_第30张图片

祝你幸福
送你一首歌《直到遇见了你我只喜欢你》陈柯宇
我去商场偶然听见,记住了高潮部分歌词 然后搜了出来,第一次听
附图:中国地图(看看以后自己会去哪,下个月写点面试经验,给以后的自己看)
鉴权系统搭建(JWT)_第31张图片

你可能感兴趣的:(微服务)