springBoot结合SpringSecurity场景中,使用jwt生成token并存放在mysql中,举个例子
时间: 2024-01-29 22:02:37 浏览: 86
在 Spring Boot 结合 Spring Security 场景中,使用 JWT 生成 token 并存放在 MySQL 中,可以按照以下步骤进行:
1. 添加 JWT 依赖:在 pom.xml 文件中添加以下依赖:
```xml
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
```
2. 编写 JWT 工具类:编写 JWT 工具类,实现 JWT 的生成、解析和验证等功能,示例代码如下:
```java
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class JwtUtils {
private static final String SECRET_KEY = "secret_key"; // 密钥
private static final long EXPIRATION_TIME = 86400000; // 过期时间(24小时)
// 生成 token
public static String generateToken(String username) {
Map<String, Object> claims = new HashMap<>();
claims.put("username", username);
return Jwts.builder()
.setClaims(claims)
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SECRET_KEY)
.compact();
}
// 解析 token
public static Claims parseToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
}
// 验证 token
public static boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
return true;
} catch (Exception e) {
return false;
}
}
}
```
3. 编写登录接口:在登录接口中,使用 JWT 工具类生成 token 并存储到 MySQL 数据库中,示例代码如下:
```java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LoginController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UserRepository userRepository;
// 登录接口
@PostMapping("/login")
public ApiResponse login(@RequestBody LoginRequest loginRequest) {
try {
// 认证用户信息
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
// 生成 token 并存储到数据库中
String token = JwtUtils.generateToken(userDetails.getUsername());
User user = userRepository.findByUsername(userDetails.getUsername());
user.setToken(token);
userRepository.save(user);
return ApiResponse.success(user);
} catch (AuthenticationException e) {
return ApiResponse.fail("Invalid username or password");
}
}
}
```
在上面的示例中,首先通过 AuthenticationManager 认证用户信息,然后使用 JwtUtils 工具类生成 token,并将 token 存储到数据库中。
4. 编写请求拦截器:在请求拦截器中,从请求头中获取 token,并使用 JwtUtils 工具类验证 token 的有效性,示例代码如下:
```java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class JwtInterceptor implements HandlerInterceptor {
@Autowired
private UserDetailsService userDetailsService;
// 在请求到达之前拦截请求
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("Authorization");
if (token != null && token.startsWith("Bearer ")) {
token = token.substring(7);
if (JwtUtils.validateToken(token)) {
String username = JwtUtils.parseToken(token).get("username").toString();
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
JwtAuthenticationToken authenticationToken = new JwtAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authenticationToken.setToken(token);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
return true;
}
}
throw new AuthenticationException("Invalid token");
}
}
```
在上面的示例中,首先从请求头中获取 token,并使用 JwtUtils 工具类验证 token 的有效性,如果 token 有效,则将用户信息保存在 SecurityContextHolder 中,后续的请求处理会使用这些信息进行身份验证。
通过以上步骤,就可以在 Spring Boot 结合 Spring Security 场景中,使用 JWT 生成 token 并存放在 MySQL 中。需要注意的是,存储 token 的表需要包含用户 ID 和 token 字段,以便后续通过用户 ID 查找 token。
阅读全文