在微服务架构中,API Gateway(网关)起到了统一入口的作用。Spring Cloud Gateway 是一个基于 Spring 5 的反向代理,提供了一系列的功能,如路由、负载均衡、授权认证等。本文将介绍如何使用 Spring Cloud Gateway 搭建一个简单的网关,并实现统一登录模块。我们将涵盖路径重写、登录拦截和跨域配置等内容。

1. Spring Cloud Gateway 的基本配置

首先,创建一个 Spring Boot 项目并添加必要的依赖。可以使用 Spring Initializr 快速创建项目,选择 Maven、Java、Spring Boot 版本,以及所需的依赖库,包括:

  • Spring Web
  • Spring Cloud Gateway
  • Spring Security
  • Spring Boot DevTools

pom.xml 中添加以下依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-test</artifactId>
    <scope>test</scope>
</dependency>

application.yml 中配置 Gateway 的基本路由:

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: http://localhost:8081
          predicates:
            - Path=/user/**
          filters:
            - RewritePath=/user/(?<segment>.*), /${segment}

这个配置中,我们将 /user/** 的请求转发至 http://localhost:8081,并通过 RewritePath 进行路径重写,使得请求路径保持一致。

2. 实现统一登录模块

为了实现统一登录,我们需要在 Gateway 中配置 Spring Security。首先,创建一个简单的用户认证服务,这里为了简化,我们使用内存存储用户信息。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/login").permitAll() // 允许所有用户访问登录接口
            .anyRequest().authenticated() // 其余请求需要认证
            .and()
            .formLogin().loginPage("/login").permitAll() // 自定义登录页面
            .and()
            .logout().permitAll(); // 允许用户登出
    }
}

3. 配置登录拦截

为了拦截未登录用户,我们可以自定义一个过滤器。在这里,我们将创建一个简单的 Token 过滤器,检查请求中的 Authorization 头是否存在。

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import reactor.core.publisher.Mono;

@Component
public class AuthGatewayFilter extends AbstractGatewayFilterFactory<AuthGatewayFilter.Config> {

    public AuthGatewayFilter() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            String token = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
            if (token == null || !isValidToken(token)) { // 检查 Token
                exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                return exchange.getResponse().setComplete();
            }
            return chain.filter(exchange);
        };
    }

    // 检查 Token 的有效性
    private boolean isValidToken(String token) {
        return "valid-token".equals(token); // 这里是简化版,实际情况应根据业务逻辑
    }

    public static class Config {
    }
}

4. 跨域配置

对于跨域请求的支持,在 application.yml 中添加跨域配置:

spring:
  cloud:
    gateway:
      globalfilters:
        - name: AddResponseHeader
          args:
            name: Access-Control-Allow-Origin
            value: "*"
        - name: AddResponseHeader
          args:
            name: Access-Control-Allow-Methods
            value: "GET, POST, PUT, DELETE, OPTIONS"

这样配置后,Gateway 将支持跨域请求。

结论

通过以上步骤,我们搭建了一个简单的 Spring Cloud Gateway,并实现了路径重写、登录拦截和跨域配置。这个简单的项目为后续的微服务架构奠定了基础,后续可以根据实际需求继续扩展功能。希望这篇文章能帮助到你,在构建微服务网关时有一个良好的开端。

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部