畅购商城:微服务网关和JWT令牌(上)

畅购商城文章系列

畅购商城:分布式文件系统FastDFS
畅购商城:商品的SPU和SKU概念
畅购商城:Lua、OpenResty、Canal实现广告缓存
畅购商城:微服务网关和JWT令牌(上)
畅购商城:微服务网关和JWT令牌(下)
畅购商城:Spring Security Oauth2 JWT(上)
畅购商城:Spring Security Oauth2 JWT(下)
畅购商城:购物车
畅购商城:订单
畅购商城:微信支付


目标

  • 掌握微服务网关的系统搭建
  • 了解什么是微服务网关以及它的作用
  • 掌握系统中心微服务的搭建
  • 掌握用户密码加密存储BCrypt
  • 掌握网关限流

1. 微服务网关

微服务网关主要作用:

  1. 整合各个微服务功能,形成一套系统;
  2. 在微服务网关中实现日志统一记录;
  3. 实现用户的操作跟踪;
  4. 实现限流操作;
  5. 用户权限认证操作;

1.1 微服务网关的概述

总结:微服务网关就是一个系统,通过暴露该微服务网关系统,方便我们进行相关的鉴权,安全控制,日志统一处理,易于监控的相关功能

不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题:

  • 客户端会多次请求不同的微服务,增加了客户端的复杂性
  • 存在跨域请求,在一定场景下处理相对复杂
  • 认证复杂,每个服务都需要独立认证
  • 难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并成一个或者将一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将会很难实施
  • 某些微服务可能使用了防火墙 / 浏览器不友好的协议,直接访问会有一定的困难

在这里插入图片描述

以上这些问题可以借助网关解决。

网关是介于客户端和服务器端之间的中间层所有的外部请求都会先经过网关这一层。也就是说,API 的实现方面更多的考虑业务逻辑,而安全、性能、监控可以交由网关来做,这样既提高业务灵活性又不缺安全性,典型的架构图如图所示:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述优点如下:

  • 安全 ,只有网关系统对外进行暴露,微服务可以隐藏在内网,通过防火墙保护。
  • 易于监控。可以在网关收集监控数据并将其推送到外部系统进行分析。
  • 易于认证。可以在网关上进行认证,然后再将请求转发到后端的微服务,而无须在每个微服务中进行认证。
  • 减少了客户端与各个微服务之间的交互次数
  • 易于统一授权

1.2 微服务网关技术

实现微服务网关的技术有很多,

  • nginx Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。
  • zuul ,Zuul 是 Netflix 出品的一个基于 JVM 路由和服务端的负载均衡器。
  • spring-cloud-gateway, 是spring 出品的 基于spring 的网关项目,集成断路器,路径重写,性能比Zuul好。

在这里插入图片描述

我们使用gateway这个网关技术,无缝衔接到基于spring cloud的微服务开发中来。

gateway官网:
gateway官网

2. 网关系统使用

2.1 需求分析

由于我们开发的系统 有包括前台系统和后台系统,后台的系统给管理员使用。那么也需要调用各种微服务,所以我们针对管理后台搭建一个网关微服务。分析如下:

在这里插入图片描述

2.2 搭建后台网关系统

2.2.1 搭建分析

由上可知道,由于 需要有多个网关,所以为了管理方便。我们新建一个项目,打包方式为pom,在里面建立各种网关系统模块即可。如图所示:
在这里插入图片描述

2.2.2 工程搭建

(1)引入依赖

修改changgou-gateway工程,打包方式为pom

pom.xml如下:

<?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>changgou-parent</artifactId>
        <groupId>com.changgou</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>changgou-gateway</artifactId>
    <packaging>pom</packaging>
    <modules>
        <module>changgou-gateway-web</module>
    </modules>

    <!--网关依赖-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

</project>

在changgou-gateway工程中,创建 changgou-gateway-web工程,该网关主要用于对后台微服务进行一个调用操作,将多个微服务串联到一起。

pom.xml:

<?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>changgou-gateway</artifactId>
        <groupId>com.changgou</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>changgou-gateway-web</artifactId>
    <description>
        普通web请求网关
    </description>
</project>

(2)引导类

在changgou-gateway-web中创建一个引导类com.changgou.GatewayWebApplication,代码如下:

@SpringBootApplication
@EnableEurekaClient
public class GatewayWebApplication {
    
    

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

(3)application.yml配置

在changgou-gateway-web的resources下创建application.yml,代码如下:

spring:
  application:
    name: gateway-web
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

2.3 跨域配置

我们需要对所有微服务跨域请求进行处理,则可以在gateway中进行跨域支持。修改application.yml,添加如下代码:

spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]': # 匹配所有请求
              allowedOrigins: "*" #跨域处理 允许所有的域
              allowedMethods: # 支持的方法
                - GET
                - POST
                - PUT
                - DELETE

最终文件如下:

spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]': # 匹配所有请求
              allowedOrigins: "*" #跨域处理 允许所有的域
              allowedMethods: # 支持的方法
                - GET
                - POST
                - PUT
                - DELETE
  application:
    name: gateway-web
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

2.4 网关过滤配置

微服务网关主要作用:路由
路由断言(下图中线上的标注):路由的规则

在这里插入图片描述路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。 路径过滤器的范围限定为特定路径。 Spring Cloud Gateway包含许多内置的GatewayFilter工厂。如上图,根据请求路径路由到不同微服务去,这块可以使用Gateway的路由过滤功能实现。

过滤器 有 20 多个 实现 类, 包括 头部 过滤器、 路径 类 过滤器、 Hystrix 过滤器 和 变更 请求 URL 的 过滤器, 还有 参数 和 状态 码 等 其他 类型 的 过滤器。

内置的过滤器工厂有22个实现类,包括 头部过滤器、路径过滤器、Hystrix 过滤器 、请求URL 变更过滤器,还有参数和状态码等其他类型的过滤器。根据过滤器工厂的用途来划分,可以分为以下几种:Header、Parameter、Path、Body、Status、Session、Redirect、Retry、RateLimiter和Hystrix。

2.4.1 Host 路由

比如用户请求cloud.itheima.com的时候,可以将请求路由给http://localhost:18081服务处理,如下配置:

说明:#用户请求的域名规则的配置,所有以cloud.itheima.com的请求都将被路由http://localhost:18081微服务
在这里插入图片描述

routes:
			#id :唯一标识符
            - id: changgou_goods_route
              #用户请求需要路由到该服务【指定要路由的服务】
              uri: http://localhost:18081
              #路由断言:路由规则配置
              predicates:
              #用户请求的域名规则的配置,所有以cloud.itheima.com的请求都将被路由http://localhost:18081微服务
              - Host=cloud.itheima.com**

2.4.2 路径匹配过滤配置

我们还可以根据请求路径实现对应的路由过滤操作,例如请求中以/brand/路径开始的请求,都直接交给http://localhost:180801服务处理,如下配置:

说明:
#所有以/brand开始的请求,都路由http://localhost:180801微服务

在这里插入图片描述上图配置如下:

routes:
            - id: changgou_goods_route
              uri: http://localhost:18081
              predicates:
              - Path=/brand/**

2.4.3 PrefixPath 过滤配置

用户每次请求路径的时候,我们可以给真实请求加一个统一前缀,例如用户请求http://localhost:8001的时候我们让它请求真实地址http://localhost:8001/brand,如下配置:

说明:
#用户请求/brand,并且将该请求路由到http://loacalhost:18081微服务

#所有以/api/brand的请求,都被路由http://loacalhost:18081微服务
#希望该路径由微服务网关自动给我添加上/api前缀,每次请求真实微服务网关的时候,需要使用微服务网关将/api去掉。

在这里插入图片描述上图配置如下:

routes:
            - id: changgou_goods_route
              uri: http://localhost:18081
              predicates:
              #- Host=cloud.itheima.com**
              - Path=/**
              filters:
              - PrefixPath=/brand

2.4.4 StripPrefix 过滤配置

很多时候也会有这么一种请求,用户请求路径是/api/brand,而真实路径是/brand,这时候我们需要去掉/api才是真实路径,此时可以使用SttripPrefix功能来实现路径的过滤操作,如下配置:

说明:
#将请求路径中的第1个路径去掉,请求路径以 / 区分,一个 / 代表一个路径。

在这里插入图片描述上图配置如下:

routes:
            - id: changgou_goods_route
              uri: http://localhost:18081
              predicates:
              #- Host=cloud.itheima.com**
              - Path=/**
              filters:
              #- PrefixPath=/brand
              - StripPrefix=1

2.4.5 LoadBalancerClient 路由过滤器(客户端负载均衡)

上面的路由配置每次都会将请求给指定的URL处理,但如果在以后生产环境,并发量较大的时候,我们需要根据服务的名称判断来做负载均衡操作,可以使用LoadBalancerClientFilter来实现负载均衡调用。LoadBalancerClientFilter会作用在url以lb开头的路由,然后利用loadBalancer来获取服务实例,构造目标requestUrl,设置到GATEWAY_REQUEST_URL_ATTR属性中,供NettyRoutingFilter使用。


修改application.yml配置文件,代码如下:
在这里插入图片描述上图配置如下:

routes:
            - id: changgou_goods_route
              #uri: http://localhost:18081
              #lb:使用LoadBalancerClient实现负载均衡,后面goods是微服务的名称【主要应用于集群环境】
              uri: lb://goods
              predicates:
              #- Host=cloud.itheima.com**
              - Path=/**
              filters:
              #- PrefixPath=/brand
              - StripPrefix=1

2.5 网关限流

网关可以做很多的事情,比如,限流,当我们的系统被频繁的请求的时候,就有可能将系统压垮,所以为了解决这个问题,需要在每一个微服务中做限流操作,但是如果有了网关,那么就可以在网关系统做限流,因为所有的请求都需要先通过网关系统才能路由到微服务中
在这里插入图片描述
上图解释说明:网关有两层网关,第一层是Nginx网关,Nginx网关主要是针对大量请求容量的抵御,它释放的流量到微服务网关也是比较大的,通过微服务网关做一个限流,控制每一个微服务的流量,这样可以对每个微服务达到一个保护的作用,防止雪崩效应。

2.5.1 思路分析

在这里插入图片描述

2.5.2 令牌桶算法

令牌桶算法是比较常见的限流算法之一,大概描述如下:

1)所有的请求在处理之前都需要拿到一个可用的令牌才会被处理; 2)根据限流大小,设置按照一定的速率往桶里添加令牌;
3)桶设置最大的放置令牌限制,当桶满时、新添加的令牌就被丢弃或者拒绝;
4)请求达到后首先要获取令牌桶中的令牌,拿着令牌才可以进行其他的业务逻辑,处理完业务逻辑之后,将令牌直接删除;
5)令牌桶有最低限额,当桶中的令牌达到最低限额的时候,请求处理完之后将不会删除令牌,以此保证足够的限流

如下图:
在这里插入图片描述

在这里插入图片描述这个算法的实现,有很多技术,Guaua是其中之一,Redis客户端也有其实现。

2.5.3 使用令牌桶进行请求次数限流

spring cloud gateway 默认使用redis的RateLimter限流算法来实现。所以我们要使用首先需要引入Redis的依赖。

(1)引入Redis依赖

在changgou-gateway的pom.xml中引入Redis的依赖

<!--redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
    <version>2.1.3.RELEASE</version>
</dependency>

(2)定义KeyResolver(唯一标识)

在Applicatioin引导类中添加如下代码,KeyResolver用于计算某一个类型的限流的KEY也就是说,可以通过KeyResolver来指定限流的Key。

我们可以根据IP来限流,比如每个IP每秒钟只能请求一次,在GatewayWebApplication定义key的获取,获取客户端IP,将IP作为key,如下代码:

说明:
#创建用户唯一标识,使用IP作为用户唯一标识,来根据IP进行限流操作。

/***
 * 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)修改application.yml中配置项,指定限制流量的配置以及Redis的配置,如图

在这里插入图片描述配置代码如下:

spring:
  cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/**]': # 匹配所有请求
              allowedOrigins: "*" #跨域处理 允许所有的域
              allowedMethods: # 支持的方法
                - GET
                - POST
                - PUT
                - DELETE
      routes:
            - id: changgou_goods_route
              uri: lb://goods
              predicates:
              - Path=/api/brand**
              filters:
              - StripPrefix=1
              - name: RequestRateLimiter #请求数限流 名字不能随便写 ,使用默认的facatory
                args:
                  key-resolver: "#{@ipKeyResolver}"
                  #每秒钟只允许有1个请求
                  redis-rate-limiter.replenishRate: 1
                  #允许并发有4个请求【宽限的个数】
                  redis-rate-limiter.burstCapacity: 4

  application:
    name: gateway-web
  #Redis配置
  redis:
    host: 192.168.211.132
    port: 6379

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

解释:

redis-rate-limiter.replenishRate是您希望允许用户每秒执行多少请求,而不会丢弃任何请求。这是令牌桶每秒填充平均速率。

redis-rate-limiter.burstCapacity是指令牌桶的容量,允许在一秒钟内完成的最大请求数,将此值设置为零将阻止所有请求。

key-resolver: 用于限流的键的解析器的 Bean 对象的名字。它使用 SpEL 表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象。

通过在 replenishRate和中设置相同的值来实现稳定的速率 burstCapacity。设置 burstCapacity高于时,可以允许临时突发 replenishRate。在这种情况下,需要在突发之间允许速率限制器一段时间(根据 replenishRate),因为2次连续突发将导致请求被丢弃( HTTP429-TooManyRequests

key-resolver: “#{@userKeyResolver}” 用于通过SPEL表达式来指定使用哪一个KeyResolver.

如上配置:

表示 一秒内,允许 一个请求通过,令牌桶的填充速率也是一秒钟添加一个令牌。

最大突发状况也只允许 一秒内有一次请求,可以根据业务来调整 。

多次请求会发生无法访问情况。

4)测试

启动redis

启动注册中心

启动商品微服务

启动gateway网关

打开浏览器 http://localhost:9101/goods/brand

快速刷新,当1秒内发送多次请求,就会返回429错误。

3. 用户登录

项目中有2个重要角色,分别为管理员和用户,我们将实现购物下单和支付,用户如果没登录是没法下单和支付的,所以我们这里需要实现一个登录功能。

3.1 BCrypt密码加密

在用户模块,对于用户密码的保护,通常都会进行加密。我们通常对密码进行加密,然后存放在数据库中,在用户进行登录的时候,将其输入的密码进行加密然后与数据库中存放的密文进行比较,以验证用户密码是否正确。

目前,MD5和BCrypt比较流行。相对来说,BCrypt比MD5更安全。

3.2 表结构介绍

用户信息表 tb_user

CREATE TABLE `tb_user` (
  `username` varchar(50) NOT NULL COMMENT '用户名',
  `password` varchar(100) NOT NULL COMMENT '密码,加密存储',
  `phone` varchar(20) DEFAULT NULL COMMENT '注册手机号',
  `email` varchar(50) DEFAULT NULL COMMENT '注册邮箱',
  `created` datetime NOT NULL COMMENT '创建时间',
  `updated` datetime NOT NULL COMMENT '修改时间',
  `source_type` varchar(1) DEFAULT NULL COMMENT '会员来源:1:PC,2:H5,3:Android,4:IOS',
  `nick_name` varchar(50) DEFAULT NULL COMMENT '昵称',
  `name` varchar(50) DEFAULT NULL COMMENT '真实姓名',
  `status` varchar(1) DEFAULT NULL COMMENT '使用状态(1正常 0非正常)',
  `head_pic` varchar(150) DEFAULT NULL COMMENT '头像地址',
  `qq` varchar(20) DEFAULT NULL COMMENT 'QQ号码',
  `is_mobile_check` varchar(1) DEFAULT '0' COMMENT '手机是否验证 (0否  1是)',
  `is_email_check` varchar(1) DEFAULT '0' COMMENT '邮箱是否检测(0否  1是)',
  `sex` varchar(1) DEFAULT '1' COMMENT '性别,1男,0女',
  `user_level` int(11) DEFAULT NULL COMMENT '会员等级',
  `points` int(11) DEFAULT NULL COMMENT '积分',
  `experience_value` int(11) DEFAULT NULL COMMENT '经验值',
  `birthday` datetime DEFAULT NULL COMMENT '出生年月日',
  `last_login_time` datetime DEFAULT NULL COMMENT '最后登录时间',
  PRIMARY KEY (`username`),
  UNIQUE KEY `username` (`username`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';

3.3 用户微服务创建

创建工程之前,先使用代码生成器生成对应的业务代码。

(1)公共API创建

在changgou-service-api中创建changgou-service-user-api,并将pojo拷贝到工程中。

在changgou-service中创建changgou-service-user微服务,并引入生成的业务逻辑代码。

(2)依赖

在changgou-service-user的pom.xml引入如下依赖:

<?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>changgou-service</artifactId>
        <groupId>com.changgou</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>changgou-service-user</artifactId>

    <!--依赖-->
    <dependencies>
        <dependency>
            <groupId>com.changgou</groupId>
            <artifactId>changgou-service-user-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

(3)启动类创建

在changgou-service-user微服务中创建启动类com.changgou.UserApplication,代码如下:

@SpringBootApplication
@EnableEurekaClient
@MapperScan("com.changgou.user.dao")
public class UserApplication {
    
    

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

(4)application.yml配置

在changgou-service-user的resources中创建application.yml配置,代码如下:

server:
  port: 18089
spring:
  application:
    name: user
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.211.132:3306/changgou_user?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123456
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:7001/eureka
  instance:
    prefer-ip-address: true
feign:
  hystrix:
    enabled: true

3.4 登录

登录的时候,需要进行密码校验,这里采用了BCryptPasswordEncoder进行加密,需要将资料中的BCrypt导入到common工程中,其中BCrypt.checkpw(“明文”,“密文”)用于对比密码是否一致。

修改changgou-service-user的com.changgou.user.controller.UserController添加登录方法,代码如下:

/***
 * 用户登录
 */
@RequestMapping(value = "/login")
public Result login(String username,String password){
    
    
    //查询用户信息
    User user = userService.findById(username);
	//对比密码 ->密码对比:加密
    if(user!=null && BCrypt.checkpw(password,user.getPassword())){
    
    
    	//密码匹配,登录成功
        return new Result(true,StatusCode.OK,"登录成功!",user);
    }
    //密码匹配失败,登录失败,账号或者密码有误
    return  new Result(false,StatusCode.LOGINERROR,"账号或者密码错误!");
}

注意:这里密码进行了加密。

3.5 网关关联

在这里插入图片描述在我们平时工作中,并不会直接将微服务暴露出去,一般都会使用网关对接,实现对微服务的一个保护作用,如上图,当用户访问/api/user/的时候我们再根据用户请求调用用户微服务的指定方法。当然,除了/api/user/还有/api/address//api/areas//api/cities//api/provinces/都需要由user微服务处理,修改网关工程changgou-gateway-webapplication.yml配置文件,如下代码:

在这里插入图片描述上图代码如下:

spring:
  cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/**]': # 匹配所有请求
              allowedOrigins: "*" #跨域处理 允许所有的域
              allowedMethods: # 支持的方法
                - GET
                - POST
                - PUT
                - DELETE
      routes:
            - id: changgou_goods_route
              uri: lb://goods
              predicates:
              - Path=/api/goods/**
              filters:
              - StripPrefix=1
              - name: RequestRateLimiter #请求数限流 名字不能随便写 ,使用默认的facatory
                args:
                  key-resolver: "#{@ipKeyResolver}"
                  redis-rate-limiter.replenishRate: 1
                  redis-rate-limiter.burstCapacity: 1
            #用户微服务
            - id: changgou_user_route
              uri: lb://user
              predicates:
              - Path=/api/user/**,/api/address/**,/api/areas/**,/api/cities/**,/api/provinces/**
              filters:
              - StripPrefix=1

  application:
    name: gateway-web
  #Redis配置
  redis:
    host: 192.168.211.132
    port: 6379

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.6 新增管理员

3.6.1 新增管理员密码加密需求与表结构分析

新增管理员,使用BCrypt进行密码加密

3.6.2 管理员登录密码验证

需求分析:

系统管理用户需要管理后台,需要先输入用户名和密码进行登录,才能进入管理后台。

思路:

用户发送请求,输入用户名和密码。

后台管理微服务controller接收参数,验证用户名和密码是否正确,如果正确则返回用户登录成功结果。

代码实现:

(1)新增方法定义

 
/**
 * 登录验证密码
 * @param admin
 * @return
 */
    
boolean login(Admin admin);

(2)实现此方法

 
@Override
    
public boolean login(Admin admin){
    
    
        
    //根据登录名查询管理员
        
    Admin admin1 = new Admin();
    admin1.setLoginName(admin.getLoginName());
    admin1.setStatus("1");  
    Admin admin2 = adminMapper.selectOne(admin1);//数据库查询出的对象
   
    if(admin2 == null){
    
    
        return false;
    }else{
    
    
        //验证密码, Bcrypt为spring的包, 第一个参数为明文密码, 第二个参数为密文密码
        return BCrypt.checkpw(admin.getPassword(),admin2.getPassword());
        
    }
    
}

(3)新增方法

 
/**
  * 登录
  * @param admin
  * @return
  */
  @PostMapping("/login")
  
public Result login(@RequestBody Admin admin){
    
    
	boolean login = adminService.login(admin);
	if(login){
    
    
		return new Result();
	}else{
    
    
		return new Result(false,StatusCode.LOGINERROR,"用户名或密码错误");

	}
    
}

总结

关于加密算法的简单介绍和使用JWT实现微服务鉴权放在下一篇中讲。
畅购商城:微服务网关和JWT令牌(下)

本文总结如下:

  • 掌握微服务网关的系统搭建
  • 了解什么是微服务网关以及它的作用
  • 掌握系统中心微服务的搭建
  • 掌握用户密码加密存储BCrypt
  • 掌握网关限流

猜你喜欢

转载自blog.csdn.net/weixin_42871468/article/details/114027271