spring boot Java 写一个JWT验证用户登录账户和密码
时间: 2023-05-23 09:04:00 浏览: 249
可以的,以下是一份简单的 Spring Boot Java JWT 用户验证的代码示例。
首先,需要添加以下依赖项到 pom.xml 文件中:
```
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
```
在 Spring Boot 应用程序的配置文件中添加以下代码:
```
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsService;
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Bean
public JwtAuthenticationFilter authenticationTokenFilterBean() throws Exception {
return new JwtAuthenticationFilter();
}
@Override
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean(BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
}
}
```
在上面的代码中,我们定义了一个 SecurityConfig 类,这是一个 Spring Security 的配置。其中 @EnableWebSecurity 注释表示我们要启用 Spring Security 的 Web 安全功能。
接下来,我们需要定义一个用于验证用户身份的服务:
```
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found with username: " + username));
return UserPrincipal.create(user);
}
@Transactional
public UserDetails loadUserById(Long id) {
User user = userRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("User", "id", id));
return UserPrincipal.create(user);
}
}
```
在上面的代码中,我们定义了一个 CustomUserDetailsService 服务类,它实现了 Spring Security 的 UserDetailsService 接口。
最后,我们需要创建一个用于生成和验证 JWT 的类:
```
public class JwtTokenProvider {
@Value("${app.jwtSecret}")
private String jwtSecret;
@Value("${app.jwtExpirationInMs}")
private int jwtExpirationInMs;
public String generateToken(Authentication authentication) {
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
Date now = new Date();
Date expiryDate = new Date(now.getTime() + jwtExpirationInMs);
return Jwts.builder()
.setSubject(userPrincipal.getId().toString())
.setIssuedAt(new Date())
.setExpiration(expiryDate)
.signWith(SignatureAlgorithm.HS512, jwtSecret)
.compact();
}
public Long getUserIdFromJWT(String token) {
Claims claims = Jwts.parser()
.setSigningKey(jwtSecret)
.parseClaimsJws(token)
.getBody();
return Long.parseLong(claims.getSubject());
}
public boolean validateToken(String authToken) {
try {
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
return true;
} catch (SignatureException ex) {
logger.error("Invalid JWT signature");
} catch (MalformedJwtException ex) {
logger.error("Invalid JWT token");
} catch (ExpiredJwtException ex) {
logger.error("Expired JWT token");
} catch (UnsupportedJwtException ex) {
logger.error("Unsupported JWT token");
} catch (IllegalArgumentException ex) {
logger.error("JWT claims string is empty.");
}
return false;
}
}
```
在上面的代码中,我们定义了一个 JwtTokenProvider 类,它提供了以下三个方法:
- generateToken:用于生成 JWT。
- getUserIdFromJWT:从 JWT 中提取用户 ID。
- validateToken:用于验证 JWT。
完整的用户登录验证代码请参考下面的例子:
```
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private JwtTokenProvider tokenProvider;
@PostMapping("/login")
public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getUsernameOrEmail(), loginRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = tokenProvider.generateToken(authentication);
return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
}
@PostMapping("/register")
public ResponseEntity<?> registerUser(@Valid @RequestBody SignUpRequest signUpRequest) {
if (userRepository.existsByUsername(signUpRequest.getUsername())) {
return new ResponseEntity(new ApiResponse(false, "Username is already taken!"), HttpStatus.BAD_REQUEST);
}
if (userRepository.existsByEmail(signUpRequest.getEmail())) {
return new ResponseEntity(new ApiResponse(false, "Email Address already in use!"), HttpStatus.BAD_REQUEST);
}
// Creating user's account
User user = new User(signUpRequest.getName(), signUpRequest.getUsername(),
signUpRequest.getEmail(), signUpRequest.getPassword());
user.setPassword(passwordEncoder.encode(user.getPassword()));
User result = userRepository.save(user);
URI location = ServletUriComponentsBuilder.fromCurrentContextPath().path("/api/users/{username}")
.buildAndExpand(result.getUsername()).toUri();
return ResponseEntity.created(location).body(new ApiResponse(true, "User registered successfully"));
}
}
```
在上面的代码中,我们定义了一个 AuthController 类,该类包含了用户登录和注册的方法。其中,authenticateUser 方法用于验证用户登录,registerUser 方法用于用户注册。
登录验证请求发送到 /api/auth/login URL,注册请求发送到 /api/auth/register URL。
登录请求使用用户名或电子邮件,以及密码作为参数。如果验证成功,将生成 JWT 并在响应体中返回。
注册请求使用名称、用户名、电子邮件和密码作为参数,在保存用户到数据库之前对数据进行验证。
至此,我们已经实现了一个简单的 Spring Boot Java JWT 用户验证的应用程序。
阅读全文