【黑马头条】-day01环境搭建SpringBoot-Cloud-Nacos


文章目录

  • 1 环境搭建及简介
  • 2 项目介绍
    • 2.1 应用
    • 2.2 业务说明
    • 2.3 技术栈
    • 2.4 收获
    • 2.5 大纲
  • 3 Nacos准备
    • 3.1 安装Nacos
  • 4 初始工程搭建
    • 4.1 环境准备
      • 4.1.1 导入项目
      • 4.1.2 设置本地仓库
      • 4.1.3 设置项目编码格式
    • 4.2 全局异常
      • 4.2.1 自动装配
    • 4.3 工程主体结构
  • 5 登录功能开发
    • 5.1 需求分析
      • 5.1.1 表结构分析
      • 5.1.2 实体类ApUser的导入
      • 5.1.3 表结构中salt的解释
        • 5.1.3.1 注册过程
        • 5.1.3.2 登录过程
  • 6 用户端微服务的搭建
    • 6.1 service模块的依赖说明
    • 6.2 创建用户微服务模块
      • 6.2.1 创建引导类
      • 6.2.2 创建controller.v1、service、mapper、config
      • 6.2.3 创建resources的配置文件
        • 6.2.3.1 bootstrap.yml
        • 6.2.3.2 logback.xml
    • 6.3 整体用户端框架
  • 7 登录接口实现
    • 7.1 app登录-接口定义
      • 7.1.1 DTO的LoginDto类
      • 7.1.2 Controller层ApUserLoginController类
      • 7.1.3 Mapper层ApUserMapper接口
      • 7.1.4 Service层ApUserService接口
      • 7.1.5 实现ApUserService接口
      • 7.1.6 完善业务层接口
    • 7.2 登录思路分析
      • 7.2.1 业务层登录实现
      • 7.2.2 Controller注入
      • 7.2.3 测试
  • 8 App端网关
    • 8.1 导入依赖
    • 8.2 微服务创建网关
      • 8.2.1 AppGateway
      • 8.2.2 创建配置文件bootstrap.yml
      • 8.2.3 在Nacos中创建配置中心
  • 9 认证过滤器
    • 9.1 全局过滤器
    • 9.2 测试
  • 10 app前端项目集成
    • 10.1 Nginx反向代理和静态资源配置


1 环境搭建及简介

在这里插入图片描述

在这里插入图片描述

2 项目介绍

2.1 应用

在这里插入图片描述

2.2 业务说明

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2.3 技术栈

前端
在这里插入图片描述

后端

在这里插入图片描述

2.4 收获

在这里插入图片描述

2.5 大纲

在这里插入图片描述

3 Nacos准备

3.1 安装Nacos

在这里插入图片描述

1)拉取镜像

docker pull nacos/nacos-server:1.2.0

2)创建容器

docker run --env MODE=standalone --name nacos --restart=always -d -p 8848:8848 nacos/nacos-server:1.2.0

3)查看日志

docker logs -f nacos

在这里插入图片描述

4)访问当前Nacos

http://192.168.204.129:8848/nacos

4 初始工程搭建

4.1 环境准备

4.1.1 导入项目

在这里插入图片描述

解压heima-leadnews.zip,并且导入idea,设置jdk为1.8
在这里插入图片描述

4.1.2 设置本地仓库

respository_new.zip解压到本地仓库文件夹

打开idea-settings设置本地仓库
在这里插入图片描述

修改为
在这里插入图片描述

4.1.3 设置项目编码格式

在这里插入图片描述

4.2 全局异常

在这里插入图片描述

heima-leadnews-common模块下的com.heima.common.exception包下自定义异常类CustomException,如果我们手动抛出异常就需要抛出CustomException类

public class CustomException extends RuntimeException {

    private AppHttpCodeEnum appHttpCodeEnum;

    public CustomException(AppHttpCodeEnum appHttpCodeEnum){
        this.appHttpCodeEnum = appHttpCodeEnum;
    }

    public AppHttpCodeEnum getAppHttpCodeEnum() {
        return appHttpCodeEnum;
    }
}

另外一个类ExceptionCatch类,全局异常拦截类

注解@ControllerAdvice:ControllerAdvice本质上是一个Component,因此也会被当成组件扫描,一视同仁,扫扫扫。

  • 这个类是为那些声明了(@ExceptionHandler、@InitBinder 或 @ModelAttribute注解修饰的)方法的类而提供的专业化的@Component , 以供多个 Controller类所共享。
@ControllerAdvice  //控制器增强类
@Slf4j
public class ExceptionCatch {

    /**
     * 处理不可控异常
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponseResult exception(Exception e){
        e.printStackTrace();
        log.error("catch exception:{}",e.getMessage());

        return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
    }

    /**
     * 处理可控异常  自定义异常
     * @param e
     * @return
     */
    @ExceptionHandler(CustomException.class)
    @ResponseBody
    public ResponseResult exception(CustomException e){
        log.error("catch exception:{}",e);
        return ResponseResult.errorResult(e.getAppHttpCodeEnum());
    }
}

在heima-leadnews-model模块下的com.heima.model包下的common包下的enums包下有个枚举类AppHttpCodeEnum,用来存放对异常的说明

public enum AppHttpCodeEnum {

    // 成功段0
    SUCCESS(200,"操作成功"),
    // 登录段1~50
    NEED_LOGIN(1,"需要登录后操作"),
    LOGIN_PASSWORD_ERROR(2,"密码错误"),
    // TOKEN50~100
    TOKEN_INVALID(50,"无效的TOKEN"),
    TOKEN_EXPIRE(51,"TOKEN已过期"),
    TOKEN_REQUIRE(52,"TOKEN是必须的"),
    // SIGN验签 100~120
    SIGN_INVALID(100,"无效的SIGN"),
    SIG_TIMEOUT(101,"SIGN已过期"),
    // 参数错误 500~1000
    PARAM_REQUIRE(500,"缺少参数"),
    PARAM_INVALID(501,"无效参数"),
    PARAM_IMAGE_FORMAT_ERROR(502,"图片格式有误"),
    SERVER_ERROR(503,"服务器内部错误"),
    // 数据错误 1000~2000
    DATA_EXIST(1000,"数据已经存在"),
    AP_USER_DATA_NOT_EXIST(1001,"ApUser数据不存在"),
    DATA_NOT_EXIST(1002,"数据不存在"),
    // 数据错误 3000~3500
    NO_OPERATOR_AUTH(3000,"无权限操作"),
    NEED_ADMIND(3001,"需要管理员权限");

    int code;
    String errorMessage;

    AppHttpCodeEnum(int code, String errorMessage){
        this.code = code;
        this.errorMessage = errorMessage;
    }

    public int getCode() {
        return code;
    }

    public String getErrorMessage() {
        return errorMessage;
    }
}

4.2.1 自动装配

resource下META-INF有spring.factories,只有有微服务引用了heima-leadnews-common,服务器初始化spring容器的时候就会找到spring.factories,把spring.factories中需要自动配置的文件加载到当前微服务的容器中,也就能用全局处理器了。

在这里插入图片描述

4.3 工程主体结构

在这里插入图片描述

5 登录功能开发

5.1 需求分析

在这里插入图片描述

5.1.1 表结构分析

打开本地sql工具,引入sql脚本,创建leadnews_user,有四张表

在这里插入图片描述

在这里插入图片描述

5.1.2 实体类ApUser的导入

在heima-leadnews-model模块下创建com.heima.model.user.pojos包下创建实体类ApUser

@TableName("ap_user"):表的映射

@TableId(value = "id", type = IdType.AUTO):主键的映射

@TableField("name"):其他字段的映射

@Data
@TableName("ap_user")
public class ApUser implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /**
     * 密码、通信等加密盐
     */
    @TableField("salt")
    private String salt;

    /**
     * 用户名
     */
    @TableField("name")
    private String name;

    /**
     * 密码,md5加密
     */
    @TableField("password")
    private String password;

    /**
     * 手机号
     */
    @TableField("phone")
    private String phone;

    /**
     * 头像
     */
    @TableField("image")
    private String image;

    /**
     * 0 男
     1 女
     2 未知
     */
    @TableField("sex")
    private Boolean sex;

    /**
     * 0 未
     1 是
     */
    @TableField("is_certification")
    private Boolean certification;

    /**
     * 是否身份认证
     */
    @TableField("is_identity_authentication")
    private Boolean identityAuthentication;

    /**
     * 0正常
     1锁定
     */
    @TableField("status")
    private Boolean status;

    /**
     * 0 普通用户
     1 自媒体人
     2 大V
     */
    @TableField("flag")
    private Short flag;

    /**
     * 注册时间
     */
    @TableField("created_time")
    private Date createdTime;

}

5.1.3 表结构中salt的解释

salt:密码、通信等加密盐

5.1.3.1 注册过程

在这里插入图片描述

5.1.3.2 登录过程

在这里插入图片描述

6 用户端微服务的搭建

heima-leadnews-service模块是管理其他所有微服务模块

6.1 service模块的依赖说明

在这里插入图片描述

6.2 创建用户微服务模块

在heima-leadnews-service下创建模块

在这里插入图片描述

6.2.1 创建引导类

然后创建一个包com.heima.user,再创建一个引导类UserApplication

@SpringBootApplication: 启动类注解

@EnableDiscoveryClient :集成当前的注册中心,加入注册中心

@MapperScan("com.heima.user.mapper") :继承MybatisPlus,扫描Mapper接口,没有就在com.heima.user下创建mapper包

@SpringBootApplication
@EnableDiscoveryClient
@MapperScan("com.heima.user.mapper")
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
    }
}

6.2.2 创建controller.v1、service、mapper、config

controller.v1是不同版本的controller

在这里插入图片描述

6.2.3 创建resources的配置文件

6.2.3.1 bootstrap.yml

若application.yml 和bootstrap.yml在同一目录下:bootstrap.yml 先加载 application.yml后加载,application.yml会覆盖

创建bootstrap.yml

server:
  port: 51801
spring:
  application:
    name: leadnews-user
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.204.129:8848
      config:
        server-addr: 192.168.204.129:8848
        file-extension: yml

这里面暂时只有Nacos的配置,关于数据库的等等都需要在Nacos的配置中心进行配置

在这里插入图片描述

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/leadnews_user?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
    username: root
    password: 123sjbsjb
# 设置Mapper接口所对应的XML文件位置,如果你在Mapper接口中有自定义方法,需要进行该配置
mybatis-plus:
  mapper-locations: classpath*:mapper/*.xml
  # 设置别名包扫描路径,通过该属性可以给包中的类注册别名
  type-aliases-package: com.heima.model.user.pojos


发布查看

6.2.3.2 logback.xml

创建日志文件logback.xml

<?xml version="1.0" encoding="UTF-8"?>

<configuration>
    <!--定义日志文件的存储地址,使用绝对路径-->
    <property name="LOG_HOME" value="D:\Code\JavaCode\HeimaToutiao\logs"/>

    <!-- Console 输出设置 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>

    <!-- 按照每天生成日志文件 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <fileNamePattern>${LOG_HOME}/leadnews.%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 异步输出 -->
    <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>512</queueSize>
        <!-- 添加附加的appender,最多只能添加一个 -->
        <appender-ref ref="FILE"/>
    </appender>


    <logger name="org.apache.ibatis.cache.decorators.LoggingCache" level="DEBUG" additivity="false">
        <appender-ref ref="CONSOLE"/>
    </logger>
    <logger name="org.springframework.boot" level="debug"/>
    <root level="info">
        <!--<appender-ref ref="ASYNC"/>-->
        <appender-ref ref="FILE"/>
        <appender-ref ref="CONSOLE"/>
    </root>
</configuration>

6.3 整体用户端框架

在这里插入图片描述

7 登录接口实现

7.1 app登录-接口定义

在这里插入图片描述

7.1.1 DTO的LoginDto类

heima-leadnews-model模块下的com.heima.model.user.pojos.dtos包下创建LoginDto类

@Data
public class LoginDto {
    private String phone;
    private String password;
}

7.1.2 Controller层ApUserLoginController类

再在heima-leadnews-service模块下的com.heima.user.controller.v1下创建ApUserLoginController类

POST请求采用@RequestBody

@RestController
@RequestMapping("/api/v1/login")
public class ApUserLoginController {
    @PostMapping("/login_auth")
    public ResponseResult login(@RequestBody(required=false) LoginDto dto) {
        return null;
    }
}

7.1.3 Mapper层ApUserMapper接口

使用mybatisplus

在com.heima.user.mapper创建ApUserMapper接口

@Mapper
public interface ApUsermapper extends BaseMapper<ApUser> {

}

7.1.4 Service层ApUserService接口

public interface ApUserService extends IService<ApUser>{
}

7.1.5 实现ApUserService接口

@Service
@Transactional
@Slf4j
public class ApUserServiceImpl extends ServiceImpl<ApUsermapper, ApUser> implements ApUserService {
}

@Service标注业务层实现

@Transactional标注事务

7.1.6 完善业务层接口

public interface ApUserService extends IService<ApUser>{
    /**
     * 登录功能
     * @param dto
     * @return
     */
    public ResponseResult login(LoginDto dto);
}

实现方法

@Service
@Transactional
@Slf4j
public class ApUserServiceImpl extends ServiceImpl<ApUsermapper, ApUser> implements ApUserService {
    @Override
    public ResponseResult login(LoginDto dto) {
        return null;
    }
}

7.2 登录思路分析

7.2.1 业务层登录实现

在这里插入图片描述

在ApUserServiceImpl类中实现思路

@Service
@Transactional
@Slf4j
public class ApUserServiceImpl extends ServiceImpl<ApUsermapper, ApUser> implements ApUserService {
    @Override
    public ResponseResult login(LoginDto dto) {
        //1.正常登录 用户名、密码
        if(StringUtils.isNotBlank(dto.getPhone()) && StringUtils.isNotBlank(dto.getPassword())) {
            //1.1 查询用户信息,根据手机号查询用户信息
            ApUser dbUser = getOne(Wrappers.<ApUser>lambdaQuery().eq(ApUser::getPhone, dto.getPhone()));
            if(dbUser == null) {
                return ResponseResult.errorResult(AppHttpCodeEnum.AP_USER_DATA_NOT_EXIST, "用户不存在");
            }
            //1.2 比对密码
            String salt = dbUser.getSalt();
            String password = dto.getPassword();
            String pwd = DigestUtils.md5DigestAsHex((password + salt).getBytes());
            if(!pwd.equals(dbUser.getPassword())) {
                return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR, "密码错误");
            }
            //1.3 没问题的话,返回数据,生成jwt
            String token = AppJwtUtil.getToken(dbUser.getId().longValue());
            Map<String,Object> map=new HashMap<>();
            map.put("token",token);
            //清空敏感信息,前端只要id,手机号,昵称
            ApUser userVO=new ApUser();
            userVO.setId(dbUser.getId());
            userVO.setPhone(dbUser.getPhone());
            userVO.setName(dbUser.getName());
            map.put("user",userVO);
            return ResponseResult.okResult(map);
        }else{
            //2.游客登录
            Map<String,Object> map=new HashMap<>();
            map.put("token",AppJwtUtil.getToken(0L));
            return ResponseResult.okResult(map);
        }
    }
}

加密采用DigestUtils.md5DigestAsHex传入字节流

生成JWT令牌是使用heima-leadnews-utils模块下的com.heima.utils.common包下的AppJWTUtil

public class AppJwtUtil {

    // TOKEN的有效期一天(S)
    private static final int TOKEN_TIME_OUT = 3_600;
    // 加密KEY
    private static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY";
    // 最小刷新间隔(S)
    private static final int REFRESH_TIME = 300;

    // 生产ID
    public static String getToken(Long id){
        Map<String, Object> claimMaps = new HashMap<>();
        claimMaps.put("id",id);
        long currentTime = System.currentTimeMillis();
        return Jwts.builder()
                .setId(UUID.randomUUID().toString())
                .setIssuedAt(new Date(currentTime))  //签发时间
                .setSubject("system")  //说明
                .setIssuer("heima") //签发者信息
                .setAudience("app")  //接收用户
                .compressWith(CompressionCodecs.GZIP)  //数据压缩方式
                .signWith(SignatureAlgorithm.HS512, generalKey()) //加密方式
                .setExpiration(new Date(currentTime + TOKEN_TIME_OUT * 1000))  //过期时间戳
                .addClaims(claimMaps) //cla信息
                .compact();
    }

    /**
     * 获取token中的claims信息
     *
     * @param token
     * @return
     */
    private static Jws<Claims> getJws(String token) {
            return Jwts.parser()
                    .setSigningKey(generalKey())
                    .parseClaimsJws(token);
    }

    /**
     * 获取payload body信息
     *
     * @param token
     * @return
     */
    public static Claims getClaimsBody(String token) {
        try {
            return getJws(token).getBody();
        }catch (ExpiredJwtException e){
            return null;
        }
    }

    /**
     * 获取hearder body信息
     *
     * @param token
     * @return
     */
    public static JwsHeader getHeaderBody(String token) {
        return getJws(token).getHeader();
    }

    /**
     * 是否过期
     *
     * @param claims
     * @return -1:有效,0:有效,1:过期,2:过期
     */
    public static int verifyToken(Claims claims) {
        if(claims==null){
            return 1;
        }
        try {
            claims.getExpiration()
                    .before(new Date());
            // 需要自动刷新TOKEN
            if((claims.getExpiration().getTime()-System.currentTimeMillis())>REFRESH_TIME*1000){
                return -1;
            }else {
                return 0;
            }
        } catch (ExpiredJwtException ex) {
            return 1;
        }catch (Exception e){
            return 2;
        }
    }

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

    public static void main(String[] args) {
       /* Map map = new HashMap();
        map.put("id","11");*/
        System.out.println(AppJwtUtil.getToken(1102L));
        Jws<Claims> jws = AppJwtUtil.getJws("eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQqEMAwA_5KzhURNt_qb1KZYQSi0wi6Lf9942NsMw3zh6AVW2DYmDGl2WabkZgreCaM6VXzhFBfJMcMARTqsxIG9Z888QLui3e3Tup5Pb81013KKmVzJTGo11nf9n8v4nMUaEY73DzTabjmDAAAA.4SuqQ42IGqCgBai6qd4RaVpVxTlZIWC826QA9kLvt9d-yVUw82gU47HDaSfOzgAcloZedYNNpUcd18Ne8vvjQA");
        Claims claims = jws.getBody();
        System.out.println(claims.get("id"));

    }

}

7.2.2 Controller注入

@RestController
@RequestMapping("/api/v1/login")
public class ApUserLoginController {
    @Autowired
    private ApUserService apUserService;
    
    @PostMapping("/login_auth")
    public ResponseResult login(@RequestBody LoginDto dto) {
        return apUserService.login(dto);
    }
}

7.2.3 测试

启动redis报错

修改bootstrap.yml文件,添加redis地址

redis:
  host: 127.0.0.1
  port: 6379
  database: 0

启动,Nacos的服务管理中有leadnews-user

访问http://localhost:51801/api/v1/login/login_auth

在这里插入图片描述

8 App端网关

在这里插入图片描述
在这里插入图片描述

8.1 导入依赖

在heima-leadnews-gateway导入以下依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
     <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
    </dependency>
</dependencies>

8.2 微服务创建网关

8.2.1 AppGateway

针对各个微服务创建相应的网关

在这里插入图片描述

创建引导类com.heima.app.gateway.AppGatewayApplication

@SpringBootApplication
@EnableDiscoveryClient
public class AppGatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(AppGatewayApplication.class, args);

    }
}

8.2.2 创建配置文件bootstrap.yml

server:
  port: 51601
spring:
  application:
    name: leadnews-app-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.204.129:8848
      config:
        server-addr: 192.168.204.129:8848
        file-extension: yml

8.2.3 在Nacos中创建配置中心

在这里插入图片描述

spring:
  cloud:
    gateway:
      globalcors:
        add-to-simple-url-handler-mapping: true
        corsConfigurations:
          '[/**]':
            allowedHeaders: "*"
            allowedOrigins: "*"
            allowedMethods:
              - GET
              - POST
              - DELETE
              - PUT
              - OPTION
      routes:
        # 平台管理
        - id: user
          uri: lb://leadnews-user
          predicates:
            - Path=/user/**
          filters:
            - StripPrefix= 1
  • id: user: 这是此路由的唯一标识符。
  • uri: lb://leadnews-user: 当请求匹配到该路由时,它会被路由到"leadnews-user"服务的实例。URI的前缀"lb://"表示路由到负载均衡器。
  • predicates: 定义了路由的匹配规则。在这种情况下,请求路径必须以"/user/"开头才会匹配到此路由。
  • filters: 定义了路由的过滤器。在这里,使用了"StripPrefix"过滤器,该过滤器会将请求的路径中的一层前缀移除。具体来说,这里是将路径中的第一层"/user"移除,以便在转发请求到"leadnews-user"服务时去除不必要的前缀。

访问http://localhost:51601/user/api/v1/login/login_auth

在这里插入图片描述

9 认证过滤器

在这里插入图片描述

9.1 全局过滤器

要实现这个功能,要实现一个全局的过滤器

在heima-leadnews-gateway模块下创建com.heima.app.gateway.filter.AuthorizeFilter类用作全局过滤器

@Component
@Slf4j
public class AuthorizeFilter implements Ordered, GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1.获取Request对象和Response对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        //2.判断当前请求是否为登录请求,如果是,直接放行
        if (request.getURI().getPath().contains("/login")) {
            //放行
            return chain.filter(exchange);
        }
        //3.获取当前请求的token信息
        String token = request.getHeaders().getFirst("token");
        //4.判断token是否存在
        if(StringUtils.isBlank(token)) {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        //5.判断token是否有效
        //5.1 解析token
        try{
            Claims body = AppJwtUtil.getClaimsBody(token);
            //5.2 判断token是否有效
            int result = AppJwtUtil.verifyToken(body);
            if(result == 1||result == 2) {
                //5.3 token过期
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
        }catch (Exception e) {
            e.printStackTrace();
            //5.4 token无效
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        //6.放行
        return chain.filter(exchange);
    }

    /**
     * 过滤器的执行顺序,返回值越小,执行优先级越高
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

把AppJwtUtil放入gateway的工具包中

在这里插入图片描述

9.2 测试

包含/login直接放行

在这里插入图片描述

10 app前端项目集成

10.1 Nginx反向代理和静态资源配置

在这里插入图片描述

在这里插入图片描述

访问http://localhost:80

在这里插入图片描述

将静态资源和nginx都放在工作目录下

在nginx的conf目录下创建文件夹leadnews.conf,新建文件heimi-leadnews-app.conf

nginx端口8801然后转发到gateway端口51601,gateway添加user路径后通过Nacos路由到leadnews-user也就是端口51801完成访问

静态资源存放在D:/Code/JavaCode/HeimaToutiao/app-web/展示其目录下的index.html

upstream  heima-app-gateway{
    server localhost:51601;
}

server {
	listen 8801;
	location / {
        root D:/Code/JavaCode/HeimaToutiao/app-web/;
		index index.html;
	}
	
	location ~/app/(.*) {
		proxy_pass http://heima-app-gateway/$1;
		proxy_set_header HOST $host;  # 不改变源请求头的值
		proxy_pass_request_body on;  #开启获取请求体
		proxy_pass_request_headers on;  #开启获取请求头
		proxy_set_header X-Real-IP $remote_addr;   # 记录真实发出请求的客户端IP
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  #记录代理信息
	}
}

在nginx.conf中引入

#user  nobody;
worker_processes  1;

events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
	# 引入自定义配置文件
	include leadnews.conf/*.conf;
}

访问http://localhost:8801

在这里插入图片描述

访问成功

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/471205.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算法---二分查找练习-3(山脉数组的顶峰索引)

山脉数组的顶峰索引 1. 题目解析2. 讲解算法原理3. 编写代码 1. 题目解析 题目地址&#xff1a;点这里 2. 讲解算法原理 初始化两个指针 left 和 right&#xff0c;分别指向数组的起始位置和结束位置。 进入循环&#xff0c;循环条件为 left < right。 在每次循环中&…

极客早报第3期:罗斯否认插足凯特王妃婚姻;清明放假调休3天;国产伟哥去年销售近13亿

一分钟速览新闻点&#xff01; 每日简报 罗斯否认插足凯特王妃婚姻清明放假调休3天国产伟哥去年销售近13亿男子持台球杆殴打2名女店员被抓今日春分淀粉肠小王子带货日销售额涨超10倍[高中生被打伤下体休学 邯郸通报](https://www.baidu.com/s?wd高中生被打伤下体休学 邯郸通报…

Android Studio实现内容丰富的安卓视频管理平台

获取源码请点击文章末尾QQ名片联系&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动 项目编号081 1. 开发环境 android stuido 2.功能介绍 安卓端&#xff1a; 1.注册登录 2.本地视频 3.视频播放 4.收藏功能 5.网路视频 6.个人中心 7.我的收藏 8.浏览历史 3.系…

安防监控平台EasyCVR使用管理员权限登录后,平台菜单栏显示不全是什么原因?

安防视频监控系统EasyCVR视频综合管理平台&#xff0c;采用了开放式的网络结构&#xff0c;平台能在复杂的网络环境中&#xff08;专网、局域网、广域网、VPN、公网等&#xff09;将前端海量的设备进行统一集中接入与视频汇聚管理&#xff0c;平台支持设备通过4G、5G、WIFI、有…

简述Cookie、Session、JWT三者特点

三者的目的都是为了维持前端页面的登录状态。 Cookies 实现流程&#xff1a; 优点&#xff1a; 存储在客户端 帮助在客户端和服务端之间维护状态信息 缺点&#xff1a; 安全风险&#xff1a;因为存储在客户端&#xff0c;有被串改的风险 容量限制&#xff1a;4KB 可用限制…

挑战设计极限!电路仿真软件成功案例大揭秘,助您圆梦创新之路

在电子设计领域&#xff0c;电路仿真软件扮演着至关重要的角色。它们不仅能够帮助工程师们模拟和分析电路的性能&#xff0c;还能够加速设计过程&#xff0c;降低成本&#xff0c;提高产品的质量和可靠性。今天&#xff0c;让我们一起挑战设计极限&#xff0c;揭秘电路仿真软件…

最新955不加班的神仙公司名单,收藏起来慢慢看!

今天给大家介绍一个Github上神奇的项目-955.WLB&#xff0c;目前已经有33.8k个star。 这里的955指的是工作作息时间&#xff0c;早九晚五&#xff0c;每周五天&#xff1b;而 WLB 是英文 Work Life Balance 的缩写&#xff0c;意为工作生活平衡。 简简单单六个字母&#xff0c…

Linux--Ubuntu安装

Linux操作系统时程序员必须要学的操作系统。接下来我们就来看一下Linux操作系统是如何安装的 我们在 Vmware 虚拟机中安装 linux 系统&#xff0c;所以需要先安装 vmware 软件&#xff0c;然后再 安装 Linux 系统。 一.所需安装文件&#xff1a; Vmware 下载地址(现在最新版的…

vulhub中fastjson 1.2.24 反序列化导致任意命令执行漏洞复现

fastjson在解析json的过程中&#xff0c;支持使用autoType来实例化某一个具体的类&#xff0c;并调用该类的set/get方法来访问属性。通过查找代码中相关的方法&#xff0c;即可构造出一些恶意利用链。 环境运行后&#xff0c;访问http://your-ip:8090即可看到JSON格式的输出。 …

Maven 环境一键部署

文章目录 一、场景说明二、脚本职责三、参数说明四、操作示例五、注意事项 一、场景说明 本自动化脚本旨在为提高研发、测试、运维快速部署应用环境而编写。 脚本遵循拿来即用的原则快速完成 CentOS 系统各应用环境部署工作。 统一研发、测试、生产环境的部署模式、部署结构、…

Linux发布项目(包括前端和后端)到OpenEuler虚拟机上

后端&#xff1a;SpringBoot 前端&#xff1a;VUE3 操作系统&#xff1a;Linux 虚拟机&#xff1a;OpenEuler 发布项目是需要关闭虚拟机上的防火墙 systemctl stop firewalld 一、发布后端项目到虚拟机 1打包后端项目为jar包 2将打包后的jar包放到虚拟机 /opt 目录下 3 运行项…

【开发环境搭建篇】IDEA安装和配置

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过大学刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0…

Spring Boot:筑基

Spring Boot 前言概述使用 Intellij idea 快速创建 Spring Boot 项目注意事项 前言 在学习 Spring 、SpringMVC 、MyBatis 和 JPA 框架的过程中&#xff0c;了解到 SSM 框架为 Java Web 开发提供了强大的后端支持&#xff0c;JPA 框架则简化了数据库的操作。然而&#xff0c;S…

免费分享一套SpringBoot+Vue大学新生报到管理系统,帅呆了~~

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue大学新生报到管理系统&#xff0c;分享下哈。 项目视频演示 【免费】SpringBootVue大学新生报到管理系统 Java毕业设计_哔哩哔哩_bilibili【免费】SpringBootVue大学新生报到管理系统 Java毕…

2旧版本navicat更换颜色/护眼背景(利用regedit注册表编辑器 )

2navicat默认的背景颜色是白色的&#xff0c;新版本可以如图直接在工具选项里面设置&#xff0c;可以先检查一下&#xff0c;如果没有相关设置&#xff0c;如果没有再往后看解决方法 另外&#xff0c;还可以安装其他护眼软件&#xff0c;但 若是设置里没有这个选项&#xff0c;…

C语言经典算法-9

文章目录 其他经典例题跳转链接46.稀疏矩阵47.多维矩阵转一维矩阵48.上三角、下三角、对称矩阵49.奇数魔方阵50.4N 魔方阵51.2(2N1) 魔方阵 其他经典例题跳转链接 C语言经典算法-1 1.汉若塔 2. 费式数列 3. 巴斯卡三角形 4. 三色棋 5. 老鼠走迷官&#xff08;一&#xff09;6.…

RAPTOR:树结构的索引和检索系统的递归抽象处理

论文地址&#xff1a;https://arxiv.org/pdf/2401.18059.pdf 摘 要 增强型检索语言模型能够更好地适应世界状态的变化&#xff0c;并整合长尾知识&#xff0c;然而现有大多数方法仅能从检索语料库中检索到较短的连续文本片段&#xff0c;这限制了对整个文档上下文的整体理解。…

【MySQL】-update的两阶段提交

每一次的更新操作都需要写进磁盘&#xff0c;然后磁盘也要找到对应的那条记录&#xff0c;然后再更新&#xff0c;整个过程IO成本、查找成本都很高。 为解决该问题&#xff0c;优先写入日志&#xff0c;然后写入磁盘。WAL&#xff08;Write-Ahead Logging&#xff09;技术 1、…

点云配准:Open3D手动选点配准工具

写在前面 本文内容 Open3D手动选点配准工具&#xff1b;包含CMakeLists&#xff0c;cpp源码&#xff0c;编译脚本&#xff0c;运行结果可视化&#xff0c;可执行文件&#xff1b;源码、编译好的工具和脚本在这里下载&#xff1a; 本博客资源链接/share_noel/csdn/open3d/open3d…

SAP 配额修改 + 修改记录写入实现

前一周 写了文章 思考了SAP 修改记录写入的思考-CSDN博客 紧接着 小家伙 感染了支原体 反反复复 &#xff0c;代码没有落地&#xff0c;今天终于落地了&#xff0c;下面把代码贴出来。 FUNCTION ZRFC_MM_QUOTA_BAPI. *"----------------------------------------------…