将登录的Token存储在Redis中可以带来以下好处:
-
提高安全性:将Token存储在Redis中,比将Token保存在本地Cookie或浏览器存储中更加安全,因为攻击者无法访问您的服务器上存储的Token。此外,由于Redis支持设置过期时间,可以通过设置Token的过期时间来自动删除旧Token,进一步提高安全性。
-
分布式部署:如果您的应用程序采用分布式部署架构,则在每个节点上保存Token可能不是最佳选择,因为这会增加管理和同步Token的复杂性。使用Redis作为统一的Token存储介质可以简化这个过程,并确保所有节点都可以访问相同的Token。
-
支持多端登录:如果您的应用程序允许用户从多个设备或浏览器登录,则必须跨设备/浏览器共享Token。将Token存储在Redis中可以轻松实现此目标,因为所有设备和浏览器都可以访问相同的Redis服务器。
-
高效查询:由于Redis是一个内存中的数据存储系统,因此它具有快速的读取和写入速度。与传统数据库相比,Redis的响应时间更短,可以提高整个应用程序的性能。
总之,将登录Token存储在Redis中可以提高应用程序的安全性、可伸缩性和性能,是一种非常流行的实践方式。
首先,确保你已经在项目中添加了spring-boot-starter-data-redis
和spring-boot-starter-security
依赖。接下来,我们将分为以下几个部分完成实现:
- 配置Redis
- 实现Token生成
- 编写登录逻辑
1. 配置Redis
在application.properties
或者application.yml
文件中配置Redis连接信息:
spring.redis.host=your_redis_host
spring.redis.port=your_redis_port
2. 实现Token生成
创建一个工具类JwtUtil
用于生成和解析JWT token。
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
public class JwtUtil {
private static final String SECRET_KEY = "your_secret_key";
public static String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public static Claims parseToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
}
}
3. 编写登录逻辑
创建一个LoginController
处理登录请求。在用户登录成功后,将生成的token与用户名存入Redis。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
@RestController
public class LoginController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private RedisTemplate<String, String> redisTemplate;
@PostMapping("/login")
public String login(@RequestBody LoginForm form) {
// 登录验证
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(form.getUsername(), form.getPassword()));
User user = (User) authentication.getPrincipal();
String token = JwtUtil.generateToken(user.getUsername());
// 将token存入Redis
ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
valueOperations.set("token:" + token, user.getUsername());
redisTemplate.expire("token:" + token, 24, TimeUnit.HOURS);
return token;
}
}
这里的LoginForm
是一个简单的登录表单类,包含用户名和密码字段:
public class LoginForm {
private String username;
private String password;
// 省略getter和setter
}
现在你已经实现了将token存入Redis并生成的基本登录功能。当然,你还需要根据实际需要配置安全设置、用户信息加载等其他相关功能。