ReactiveRedisTemplate uses FastJSON for serialization configuration
- The Reactive Redis package and the FastJSON package are first introduced in Maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
Copy the code
- Write redisAutoconfig. class to customize the ReactiveRedisTemplate Bean configuration
Here I use ReactiveRedisTemplate<String, Object> with key as String and value as Object, so that value can be manipulated directly with Java objects without the need to display fastjson serialization and deserialization.
It is important to note the new 1 RedisSerializationContext ReactiveRedisTemplate require incoming object, redis key and the value of configuration in RedisSerializationContext serialized way.
Here we use StringRedisSerializer key and hashKey serialization, use value and hashValue fastjson GenericFastJsonRedisSerializer for serialization.
@Configuration
public class RedisAutoConfig {
@Bean
public ReactiveRedisTemplate<String, Object> reactiveRedisTemplate(LettuceConnectionFactory connectionFactory) {
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
GenericFastJsonRedisSerializer fastJsonRedisSerializer = new GenericFastJsonRedisSerializer();
RedisSerializationContext.SerializationPair<String> keySerializationPair =
RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer);
RedisSerializationContext.SerializationPair<Object> valueSerializationPair =
RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer);
RedisSerializationContext.SerializationPair<Object> hashValueSerializationPair =
RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer);
RedisSerializationContext<String, Object> context = new RedisSerializationContext<String, Object>() {
@Override
public SerializationPair getKeySerializationPair(a) {
return keySerializationPair;
}
@Override
public SerializationPair getValueSerializationPair(a) {
return valueSerializationPair;
}
@Override
public SerializationPair getHashKeySerializationPair(a) {
return keySerializationPair;
}
@Override
public SerializationPair getHashValueSerializationPair(a) {
return hashValueSerializationPair;
}
@Override
public SerializationPair<String> getStringSerializationPair(a) {
returnkeySerializationPair; }};return newReactiveRedisTemplate<>(connectionFactory, context); }}Copy the code
After this configuration is complete, the ReactiveRedisTemplate<String, Object> Object can be injected directly and automatically
@Autowired
private ReactiveRedisTemplate<String, Object> reactiveRedisTemplate;
Copy the code
2. Customize token verification using ReactiveRedisTemplate in SpringCloudGateway
- Start by introducing the Spring Cloud Gateway dependency in Maven
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
Copy the code
- Writing a custom filter factory TokenVerifyGatewayFilterFactory customize token validation
First, retrieve the token field from the header of the request, query redis based on the token, and retrieve the user ID corresponding to the token. If the user ID exists, the token is valid; if not, the token is invalid.
@Component
public class TokenVerifyGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {
@Autowired
private ReactiveRedisTemplate<String, Object> reactiveRedisTemplate;
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
String token = request.getHeaders().get("token").get(0);
return this.getUserId(token).flatMap(op -> {
Check whether there is a corresponding cache in redis. If there is no cache, the token returned is invalid
if(! op.isPresent()) { ServerHttpResponse response = exchange.getResponse();byte[] bits = "The token is invalid".getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory().wrap(bits);
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().add("Content-Type"."text/plain; charset=UTF-8");
return response.writeWith(Mono.just(buffer));
}
//2. The cache is valid. Obtain the userId and perform other operations
System.out.println(Redis cache token user: + op.get());
//3. If the token authentication succeeds, run the filter command to complete the forwarding
return chain.filter(exchange);
});
};
}
private Mono<Optional<String>> getUserId(String token) {
//a. Query redis in reactive mode to obtain the value of the token
return this.reactiveRedisTemplate.opsForValue().get(token)
// select * from redis where v is the user ID of type String
.map(v -> Optional.ofNullable((String)v))
// if the token is invalid, b will not execute it
.switchIfEmpty(Mono.just(Optional.ofNullable(null))); }}Copy the code
Three, test,
- Write the SpringCloudGateway configuration file
For any uri, using TokenVerifyGatewayFilterFactory request filtering, and will be localhost: 8080 forward any request to www.baidu.com.
spring:
cloud:
gateway:
routes:
- id: testRoute
uri: https://www.baidu.com
predicates:
- Path=/**
filters:
- TokenVerify
Copy the code
- Redis cache data Settings
Cache key=”goodToken” and value=”magicTan” in Redis. That is, The goodToken is a valid token and the user ID is magicTan. If an invalidToken such as an invalidToken is used, the user id cannot be obtained.
- Run the project for testing
Call localhost:8080, set token to goodToken in header, you can see that the request is forwarded to Baidu, and the console outputs the cached user ID magicTan:
Localhost :8080, header = invalidToken, token is invalid
Project Address: Code Cloud
Please scan the code to follow my wechat official account: magicTan.