手动搭建gateway,项目集成gateway实现Token效果

这篇具有很好参考价值的文章主要介绍了手动搭建gateway,项目集成gateway实现Token效果。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景

现在想要进行token校验,故引入gateway服务。
首先阅读官网,知道概念:Gateway官网详解

步骤

1、首先创建springboot项目

看整体的目录结构
手动搭建gateway,项目集成gateway实现Token效果,AR项目总结,gateway,cloud

2、引入依赖

 <dependencies>
        <!--gateway的依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--nacos注册与发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--nacos配置中心来做配置管理-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

        <dependency>
            <groupId>com.tfjybj</groupId>
            <artifactId>fewCode-common-redis</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>


    </dependencies>

3、配置文件!!!!!(超级重要!!!根据自己的需要进行配置)

server:
  port: 8088
  servlet:
    context-path: /api

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: login_route
          uri: lb://fewCode-provider-login
          #uri: http://localhost:8001/
          predicates:
            - Path=/login/**,/Curriculum/**,/classes/**
          filters:
            - RewritePath=/(?<segment>.*),/$\{segment}
leyou:
  filter:  #需要进行过滤的白名单
    allowPaths:
      - /login/checkLogin
      - /login/user
      - /login/userLogin
      - /upload/file
    tokenExpire: 1440

这份配置是用于Spring Cloud Gateway的配置文件,用于构建API网关。让我来解释一下每个部分的含义:

服务器配置:

服务器监听端口为8088。
Servlet的上下文路径设置为"/api",意味着所有API的端点都将具有这个前缀。
Spring Cloud Gateway配置:

服务发现定位器:启用,这意味着网关将使用服务发现来查找后端服务的路由。在动态的微服务环境中非常有用。
路由:路由配置指定了网关如何将传入的请求路由到后端服务。在这里,定义了一个路由:
id: login_route - 这是该路由的唯一标识符。
uri: lb://fewCode-provider-login - 后端服务的URI,用于处理具有负载均衡器(lb)的请求。服务名为"fewCode-provider-login",网关将使用服务发现来定位该服务。
predicates: 定义了应用此路由的条件。在这里,该路由将用于以"/login/“、”/Curriculum/“或”/classes/"开头的路径的请求。
filters: 对请求应用的过滤器,在将其转发到后端服务之前。在这里,使用了一个RewritePath过滤器,用于删除路径末尾的斜杠。
自定义配置:

leyou:这似乎是一些与"leyou"相关的自定义配置,用于特定的过滤逻辑。
filter:这是一个允许白名单路径的配置。
allowPaths:列出的路径将无需任何额外过滤而被允许。这些路径的请求不会受到任何额外的检查。
tokenExpire:设置令牌过期的时间限制(以分钟为单位),这里设置为1440分钟(24小时)。
总体而言,这份配置将Spring Cloud Gateway配置成将传入的请求路由到名为"fewCode-provider-login"的后端服务,前提是请求路径以"/login/“、”/Curriculum/“或”/classes/"开头。同时,它提供了一个白名单,允许无需任何额外过滤的路径。

4、相关类

package com.tfjybj.gateway.config;


import com.tfjybj.gateway.filter.AuthorizeFilter;
import com.tfjybj.gateway.filter.RenewFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class FilterConfig {

    @Bean
    public AuthorizeFilter authGatewayFilter() {
        //配置拦截器参数
        //order:序号,设置拦截器执行顺序,AuthGatewayFilter为1
        return new AuthorizeFilter(0);
    }

    @Bean
    public RenewFilter renewFilter(){
        // 续约Token
        return new RenewFilter(5);
    }



}

package com.tfjybj.gateway.config;

import com.tfjybj.gateway.util.FilterProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 请求白名单
 *

 */
@Component
public class IgnorePath {

    @Autowired
    private FilterProperties filterProperties;

    public boolean isAllowPath(String path) {
        //遍历白名单
        for (String allowPath : filterProperties.getAllowPaths()) {
            //判断是否允许
            if(path.startsWith(allowPath)){
                return true;
            }
        }
        return  false;
    }

}

package com.tfjybj.gateway.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;

@Configuration
public class LapCorsConfiguration {
    @Bean
    public CorsWebFilter corsWebFilter(){
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

        CorsConfiguration corsConfiguration = new CorsConfiguration();

        //1、配置跨域
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.setAllowCredentials(true);

        source.registerCorsConfiguration("/**",corsConfiguration);
        return new CorsWebFilter(source);
    }
}

package com.tfjybj.gateway.filter;

import com.alibaba.fastjson.JSON;

import com.tfjybj.gateway.config.IgnorePath;
import com.tfjybj.gateway.result.ResultMsgEnum;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.HashMap;


public class AuthorizeFilter implements GlobalFilter, Ordered {

    private static final Logger log = LogManager.getLogger();

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Autowired
    private IgnorePath ignorePath;

    private final int order;

    public AuthorizeFilter(int order) {
        this.order = order;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();

        //获取请求的url路径
        String path = request.getURI().getPath();
        boolean flag=ignorePath.isAllowPath(path);
        if (flag) {
            log.info("请求在白名单中,metaverse.filter: {}",path);
            return chain.filter(exchange);
        } else {

            //获取token值
            String authorization = headers.getFirst("Authorization");
            log.info("Authorization值{}", authorization);
            authorization = authorization.split("Bearer ")[1];
            //判断redis中是否有token
            Boolean aBoolean = redisTemplate.hasKey("fewCode:userinfo:" + authorization);
            if (aBoolean){
                return chain.filter(exchange);
            }else {
                //声明变量
                ServerHttpResponse response = exchange.getResponse();
                HashMap map = new HashMap();
                String resp;
                DataBuffer bodyDataBuffer;

                //设置响应头
                response.setStatusCode(HttpStatus.FORBIDDEN);
                map.put("code", "403");
                map.put("message", ResultMsgEnum.AUTH_FAILED.getMsg());
                resp = JSON.toJSONString(map);
                bodyDataBuffer = response.bufferFactory().wrap(resp.getBytes());
                response.getHeaders().add("Content-Type","application/json;charset=UTF-8");
                return response.writeWith(Mono.just(bodyDataBuffer));

            }


        }
    }


    @Override
    public int getOrder() {
        return this.order;
    }

}

package com.tfjybj.gateway.filter;

import com.tfjybj.gateway.config.IgnorePath;
import com.tfjybj.gateway.util.FilterProperties;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.concurrent.TimeUnit;

/**
 * token续约的逻辑
 *

 */
public class RenewFilter implements GlobalFilter, Ordered {


    private static final Logger log = LogManager.getLogger();

    private final int order;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public RenewFilter(int order) {
        this.order = order;
    }

    @Autowired
    private IgnorePath ignorePath;

    @Autowired
    private FilterProperties filterProperties;

    @Override
    public int getOrder() {
        return this.order;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();

        //获取请求的url路径
        String path = request.getURI().getPath();
        boolean flag=ignorePath.isAllowPath(path);
        if (flag) {
            log.info("请求在白名单中,metaverse.filter: {}", path);
            return chain.filter(exchange);
        }
        //token值
        String authorization = headers.getFirst("Authorization");
        authorization = authorization.split("Bearer ")[1];
        log.info("Authorization值{}", authorization);


        //TOKEN续活


        //解析TOKEN


        //根据uuid,延长用户信息
        String uuid = authorization;
        String key = "fewCode:userinfo:" + uuid;
        stringRedisTemplate.expire(key, filterProperties.getTokenExpire(), TimeUnit.MINUTES);


        return chain.filter(exchange);

    }



}

package com.tfjybj.gateway.result;

public enum ResultMsgEnum {

    FIND_SUCCESS("查询成功!"),
    FIND_FAIL("查询失败!"),

    UPDATE_SUCCESS("更新成功"),
    UPDATE_FAIL("更新失败"),

    DELETE_SUCCESS("删除成功"),
    DELETE_FAIL("删除失败"),

    SEND_SUCCESS("发送成功"),
    SEND_FAIL("发送失败"),

    EXECUTE_SUCCESS("执行成功!"),
    EXECUTE_FAIL("执行失败!"),

    AUTH_FAILED("权限认证失败"),
    AUTH_SUCCESS("权限认证成功");

    private final String msg;

    ResultMsgEnum(String msg) {
        this.msg = msg;
    }

    public String getMsg() {
        return msg;
    }
}

package com.tfjybj.gateway.util;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

import java.util.List;


@Component
@RefreshScope
@ConfigurationProperties(prefix = "leyou.filter")
public class FilterProperties {
    public void setAllowPaths(List<String> allowPaths) {
        this.allowPaths = allowPaths;
    }

    public List<String> getAllowPaths() {
        return allowPaths;
    }

    private List<String> allowPaths;

    /**
     * token过期时间
     */
    private Integer tokenExpire;

    public Integer getTokenExpire() {
        return tokenExpire;
    }

    public void setTokenExpire(Integer tokenExpire) {
        this.tokenExpire = tokenExpire;
    }
}

package com.tfjybj.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
//@EnableDiscoveryClient

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

}

我们在服务中进行的白名单中接口的操作如下

(主要是根据传过来的信息生成token,然后以键值对的形式存入redis中,方便后续通过redis根据token拿人的信息):

RestController
@RequestMapping("/login")
public class LoginController {

    @Autowired
    private Actor actorInfo;

    @ApiOperation("学生登录验证")
    @RequestMapping(value="checkLogin",method= RequestMethod.POST)
    @Transactional(rollbackFor = Exception.class)
    public Actor checkLoginInfo(@RequestBody Actor actor){
        return actorInfo.notifyStudentCheckLoginInfo(actor);
    }
}
public Actor notifyStudentCheckLoginInfo(Actor student){
        Actor actor;
        for (Actor studentInfo:allStudent){
            actor=studentInfo.checkLoginInfo(student);
            if (!ObjectUtils.isEmpty(actor)){
                //生成UUID
                String uuid = CreateUUID.createUUID();
                //存入redis
                saveRedis(uuid, actor);
                //生成token,封装到请求头
                putHeader(uuid);
                return actor;
            }
        }
        return null;
    }
public class CreateUUID {
    public CreateUUID() {
    }

    public static String createUUID() {
        String preUuid = UUID.randomUUID().toString();
        String newUUID = preUuid.replace("-", "");
        return newUUID;
    }
}
   private void saveRedis(String uuid, Object userInfo) {
        //拼接key,user信息序列化,存入redis,过期时间在nacos中设置
        String key = "fewCode:userinfo:" + uuid;
        String userJson = JSONObject.toJSONString(userInfo);
        redisTemplate.opsForValue().set(key, userJson);
        redisTemplate.expire(key, 1440, TimeUnit.MINUTES);
    }
   private void putHeader(String token) {
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = sra.getResponse();
        response.setHeader("Authorization", token);
    }

测试

存:

手动搭建gateway,项目集成gateway实现Token效果,AR项目总结,gateway,cloud

手动搭建gateway,项目集成gateway实现Token效果,AR项目总结,gateway,cloud
将断点打到这里,可以观察到我们要请求的服务IP+端口号还有url地址,如下
相当手动访问

手动搭建gateway,项目集成gateway实现Token效果,AR项目总结,gateway,cloud

调通后存入redis中如下

手动搭建gateway,项目集成gateway实现Token效果,AR项目总结,gateway,cloud

拿:

然后拿着根据token获取信息

手动搭建gateway,项目集成gateway实现Token效果,AR项目总结,gateway,cloud

手动搭建gateway,项目集成gateway实现Token效果,AR项目总结,gateway,cloud

package com.tfjybj.login.service.impl;

import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Service
public class AnalysisTokenService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 获取当前登陆人id
     *
     * @return
     */
    public String getUserId() {
        JSONObject userData = getUserData();
        return userData.get("id").toString();
    }

    /**
     * 获取用户code
     *
     * @return
     */
    public String getUserAccount() {
        JSONObject userData = getUserData();
        return userData.get("account").toString();
    }

    /**
     * 获取当前登陆人name
     *
     * @return
     */
    public String getUserName() {
        JSONObject userData = getUserData();
        return userData.get("name").toString();

    }

    public JSONObject getUserData() {
        //从请求头获取token
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String token = sra.getRequest().getHeader("Authorization");
        token = token.split("Bearer ")[1];
        //解析token
        JSONObject userJson = this.analysisToken(token);
        return userJson;
    }


    public JSONObject analysisToken  (String token){

        //解析token
        String key= "fewCode:userinfo:"+token;
        String userInfoStr = redisTemplate.opsForValue().get(key);
        JSONObject userJson = JSONObject.parseObject(userInfoStr);
//        String data = jsonObject.get("data").toString();
//        JSONObject userJson = JSONObject.parseObject(data);
        return userJson;

    }

}

总结

1、搞懂gateway是干嘛的
2、知道配置文件中各个参数是什么文章来源地址https://www.toymoban.com/news/detail-615150.html

到了这里,关于手动搭建gateway,项目集成gateway实现Token效果的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • GateWay网关自定义过滤器实现token校验完成统一鉴权

    gateWay---API网关,也可以称为业务网关,主要服务于微服务的; (1)  三大组件 路由(Route)         构建网关的基本模块,由id(唯一标示)、目标URI、一组断言、一组过滤器组成,如果断言为true,则匹配该路由   断言(Predicate)          可以使用它匹配来自HTTP请求的任何

    2024年02月08日
    浏览(51)
  • SpringBoot集成JWT token实现权限验证

    先在pom中引入 JWT依赖 然后引入一个生成的 token 的工具类         然后具体实现上有两种方式,一个是使用自定义注解配合拦截器,另外一个是使用拦截器。 方法一:         先自定义个注解,然后再定义一个自定义拦截器 JwtInterceptor 类,同时让 JwtInterceptor 类继承

    2024年02月10日
    浏览(58)
  • 3-2. SpringBoot项目集成【用户身份认证】实战 【实战核心篇】基于JWT生成和校验Token

    书接上文 技术选型篇,我们做了【用户身份认证】的技术选型说明,对基于 Session、Token、JWT 的方案进行了详细的对比分析,详细说明了它们都是什么和各自的优缺点!这些是实战的基础,还没看过的同学,建议先看上文。最终采用的是目前流行的 基于JWT的Token用户身份认证

    2023年04月08日
    浏览(51)
  • 3-1. SpringBoot项目集成【用户身份认证】实战 【技术选型篇】基于Session、Token、JWT怎么选?

    通过第二章2-2. SpringBoot API开发详解 --SpringMVC注解+封装结果+支持跨域+打包,我们实现了基于SpringBoot项目的 API接口开发 ,并实现 API结果统一封装、支持跨域请求 等等功能,接下来开始第三章,主要做用户身份认证,主要实现一套 统一鉴权的用户身份认证的机制 。 我已经提

    2024年01月22日
    浏览(55)
  • 【Android】使用ViewPager2实现轮播图效果,手动/自动轮播图

    这里使用Gilde进行加载图片:Glide 使用Gilde可以加载网络图片还可以提高图片加载性能。 接下来新建一个子布局item_image,加载viewPage2的子布局。 ViewPage2就是使用recyclerView实现的,所以这里使用方法其实类似。 这里直接继承RecyclerView.Adapter即可,代码很简单不必多说。 创建一个

    2024年02月03日
    浏览(50)
  • SpringCloud nacos 集成 gateway ,实现动态路由

    🎈 作者: Linux猿 🎈 简介: CSDN博客专家🏆,华为云享专家🏆,Linux、C/C++、云计算、物联网、面试、刷题、算法尽管咨询我,关注我,有问题私聊! 🎈 欢迎小伙伴们点赞👍、收藏⭐、留言💬 目录 一、准备工作 1.1 下载代码 1.2 运行代码 二、集成 gateway 2.1 修改 pom.xml 2

    2024年02月16日
    浏览(33)
  • Spring Cloud Gateway集成Nacos实现负载均衡

    💡Nacas可以用于实现Spring Cloud Gateway中网关动态路由功能,也可以基于Nacos来实现对后端服务的负载均衡,前者利用Nacos配置中心功能,后者利用Nacos服务注册功能。 接下来我们来看下Gateway集成Nacos实现负载均衡的架构图 一. 环境准备 1. 版本环境 Jdk: java.version1.8/java.version Spr

    2024年02月10日
    浏览(60)
  • 【SpringSecurity】十一、SpringSecurity集成JWT实现token的方法与校验

    添加JWT的maven依赖: application.yaml中配置密钥的值,方便代码中引用和后续更改: 这里的命名改为JWTService好点,Utils命名似乎偏静态方法一点。 再贴一下下统一结果类的定义: 下面是安全用户类,用于在数据库的用户对象类SysUser和返给框架的官方对象类UserDetails之间做过渡转

    2024年02月10日
    浏览(42)
  • 【实现微服务集成satoken在网关gateway处统一鉴权】

    本文旨在使用开源轻量级 Java 权限认证框架sa-token+springcloud-gateway实现微服务在网关处统一鉴权。sa-token参考地址:https://sa-token.cc/doc.html#/ 项目按照业务分为三个板块,如图: api(也就是微服务中各种api接口,不涉及任何权限相关代码,只提供服务) auth(认证中心,实现登陆逻辑

    2024年02月10日
    浏览(44)
  • 如何使用 NestJS 集成 Passort 和 JWT Token 实现 HTTP 接口的权限管理

    💡 如果你不希望其他人可以随意进出你的房子,那么你需要给你的房子上个锁。 开发一个接口很容易,开发一个具有安全性的接口却不容易。成熟的后端服务项目最注重的一点就是如何保护系统的数据安全,不能让用户无脑的访问操作所有的数据,这是不合理更是极度危险

    2024年01月22日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包