在微服务架构中,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,并实现了路径重写、登录拦截和跨域配置。这个简单的项目为后续的微服务架构奠定了基础,后续可以根据实际需求继续扩展功能。希望这篇文章能帮助到你,在构建微服务网关时有一个良好的开端。