Firstly, I would like to explain about the advantage about cacheing.
When we use RESTFull applicatoin, most of the time, we are using token (Ex: JWT) base authentication/authorization. Since we are using token base authentication/authorization, we don't cross check the user infomation with the database. Therefore, if somebody copy the token and logout from the system, still, if he/she knows the API details, they can invoke the APIs (Using Postman, curl or similer tools). It is very unsecure, so, better to keep the token information somewhere, we can access the inforation very quickly and easily, then we can validate service invokation whether is it valid or not.
In this article I'm going to describe, how to conect and use Redis server in Spring Boot application.
Steps:
1. Start the Redis server. For this explanation I'm going to use the docker.
docker run -p 6379:6379 --name redis -v redis.conf:/usr/local/etc/redis/redis.conf -d --memory 100m redis
2. Then we need to add below dependency for the project
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
Here I'm going to use jedis client.
3. Enable caching
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class TestApplication {
....
}
4. Redis cache repository
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;
import java.util.concurrent.TimeUnit;
@Repository
public class RedisCacheRepository {
private HashOperations hashOperations;
private RedisTemplate redisTemplate;
private final Logger logger = LoggerFactory.getLogger(RedisCacheRepository.class);
private long tokenValidity = 180000;
public RedisCacheRepository(RedisTemplate redisTemplate){
this.redisTemplate = redisTemplate;
this.hashOperations = this.redisTemplate.opsForHash();
}
public void save(String tokenId) {
try {
hashOperations.put("USERS", tokenId, tokenId);
redisTemplate.expire("USERS", tokenValidity, TimeUnit.MILLISECONDS);
} catch (Exception ex) {
logger.error(ex.getMessage());
}
}
public boolean findById(String tokenId) {
boolean activeUser = false;
try {
activeUser = hashOperations.get("USERS", tokenId) != null;
} catch (Exception ex) {
logger.error(ex.getMessage());
}
return activeUser;
}
public void delete(String tokenId) {
try {
hashOperations.delete("USERS", tokenId);
} catch (Exception ex) {
logger.error(ex.getMessage());
}
}
}
Above data is just for explain purpose only.
I have added token validity period (tokenValidity), because, if user ideal and/or doesn't logout properly, we cannot delete the login info from the cache. Therefore, we can add a expire time as above.