springboot jwt token前后端分离_前后端分离之JWT用户认证
时间: 2023-06-23 11:48:09 浏览: 210
好的,关于 Spring Boot JWT Token 的前后端分离问题,我可以为您提供一些帮助。
JWT(JSON Web Token)是一种基于 JSON 的开放标准(RFC 7519),用于在网络上安全传输声明。在前后端分离的应用中,通常会使用 JWT 来实现用户认证和授权。
下面是一个简单的示例,演示了如何在 Spring Boot 应用中使用 JWT 和前后端分离的方式进行用户认证。
首先,您需要在后端应用中添加 JWT 相关的依赖。可以使用以下 Maven 依赖:
```xml
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
```
接下来,您需要编写一个 JWT 工具类,用于生成和验证 JWT。
```java
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Component
public class JwtUtils {
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private Long expiration;
private static final String CLAIM_KEY_USERNAME = "sub";
private static final String CLAIM_KEY_CREATED = "iat";
private SecretKey generateKey() {
return Keys.hmacShaKeyFor(secret.getBytes());
}
public String generateToken(String username) {
Map<String, Object> claims = new HashMap<>();
claims.put(CLAIM_KEY_USERNAME, username);
claims.put(CLAIM_KEY_CREATED, new Date());
return Jwts.builder()
.setClaims(claims)
.setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
.signWith(generateKey(), SignatureAlgorithm.HS512)
.compact();
}
public Claims getClaimsFromToken(String token) {
return Jwts.parserBuilder()
.setSigningKey(generateKey())
.build()
.parseClaimsJws(token)
.getBody();
}
public boolean isTokenExpired(String token) {
Claims claims = getClaimsFromToken(token);
Date expiration = claims.getExpiration();
return expiration.before(new Date());
}
public boolean validateToken(String token, String username) {
Claims claims = getClaimsFromToken(token);
String subject = claims.getSubject();
Date expiration = claims.getExpiration();
return subject.equals(username) && !expiration.before(new Date());
}
}
```
在这个工具类中,我们使用了 io.jsonwebtoken 库来实现 JWT 的生成和验证。在生成 JWT 时,我们使用了一个密钥(secret)来签名 JWT。在验证 JWT 时,我们还检查了 JWT 中保存的用户名和过期时间是否正确。
接下来,您需要在 Spring Boot 应用中添加一个 JWT 认证过滤器,用于在请求到达后端之前验证 JWT。
```java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private JwtUtils jwtUtils;
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
String header = request.getHeader("Authorization");
if (header != null && header.startsWith("Bearer ")) {
String token = header.substring(7);
String username = jwtUtils.getClaimsFromToken(token).getSubject();
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (jwtUtils.validateToken(token, username)) {
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
}
chain.doFilter(request, response);
}
}
```
在这个过滤器中,我们从请求头中获取 JWT,然后使用之前编写的 JwtUtils 工具类来验证 JWT。如果 JWT 验证成功,则将用户信息添加到 Spring Security 的认证上下文中。
最后,在 Spring Boot 应用中添加一个登录接口,用于生成 JWT。
```java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
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.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/auth")
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtUtils jwtUtils;
@Autowired
private UserDetailsService userDetailsService;
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) throws AuthenticationException {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
UserDetails userDetails = userDetailsService.loadUserByUsername(loginRequest.getUsername());
String token = jwtUtils.generateToken(userDetails.getUsername());
Map<String, Object> response = new HashMap<>();
response.put("token", token);
return ResponseEntity.ok(response);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
```
在这个登录接口中,我们首先使用 Spring Security 的 AuthenticationManager 来验证用户信息。如果验证成功,则使用 JwtUtils 工具类生成 JWT,并将 JWT 返回给前端应用。
以上就是一个简单的 Spring Boot JWT Token 的前后端分离示例。希望对您有所帮助!
阅读全文