📅  最后修改于: 2023-12-03 14:47:33.906000             🧑  作者: Mango
在使用 Spring Security 实现用户注册和登录功能时,用户注册后需要再手动进行一次登录操作。本篇文章将介绍如何实现用户注册后自动登录的功能。
在 pom.xml
中添加 Spring Security 的依赖:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
在 Spring Security 的配置类中添加以下配置:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// ...
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private PersistentTokenRepository tokenRepository;
@Override
protected void configure(HttpSecurity http) throws Exception {
// ...
http
// ...
.formLogin()
// ...
.successHandler(authenticationSuccessHandler())
// ...
.and()
// ...
.rememberMe()
.tokenRepository(tokenRepository)
.userDetailsService(userDetailsService)
.rememberMeCookieName("my-remember-me-cookie")
.and()
// ...
.logout()
// ...
.and()
// ...
.csrf()
.disable(); // 为了实现方便,关闭了 csrf 防护
}
@Bean
protected AuthenticationSuccessHandler authenticationSuccessHandler() {
return new SimpleUrlAuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
super.onAuthenticationSuccess(request, response, authentication);
// 自动登录逻辑
if (authentication.isAuthenticated() && CookieUtils.getCookieValue(request, "remember-me") == null) {
User user = (User) authentication.getPrincipal();
PersistentRememberMeToken token = new PersistentRememberMeToken(
user.getUsername(),
getTokenSeries(),
getTokenValue(),
new Date()
);
tokenRepository.createNewToken(token);
Cookie rememberMeCookie = new Cookie("remember-me", token.getSeries());
rememberMeCookie.setMaxAge(60 * 60 * 24 * 30); // 一个月后失效
rememberMeCookie.setPath("/");
response.addCookie(rememberMeCookie);
}
}
};
}
// ...
}
在配置中,我们主要做了以下几件事情:
authenticationSuccessHandler()
。PersistentTokenRepository
和用户详细信息服务 UserDetailsService
。authenticationSuccessHandler()
中,实现了自动登录的逻辑。如果用户已经通过身份验证,并且没有记住我 Cookie 的话,就生成新的记住我 Token 并写入浏览器的 Cookie 中。在一个简单的 Spring Boot 应用中,完成用户注册和登录的样例代码如下:
@Service
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
public UserServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public User save(User user) {
user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));
return userRepository.save(user);
}
@Override
public User findByUsername(String username) {
return userRepository.findByUsername(username);
}
}
@Controller
public class AuthController {
private final UserService userService;
public AuthController(UserService userService) {
this.userService = userService;
}
@GetMapping("/register")
public String registerPage(Model model) {
model.addAttribute("user", new User());
return "register";
}
@PostMapping("/register")
public String register(@ModelAttribute User user) {
userService.save(user);
return "redirect:/login";
}
@GetMapping("/login")
public String loginPage() {
return "login";
}
}
@RestController
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/user")
public Principal user(Principal principal) {
return principal;
}
}
@Entity
@Table(name = "users")
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true)
private String username;
private String password;
public User() {}
// getters, setters and other UserDetails methods
}
在样例代码中,我们通过 UserService
实现了用户注册和找到用户等业务逻辑,通过 AuthController
实现了注册页面和登录页面的访问,通过 UserController
实现了用户信息的获取。具体逻辑请根据实际情况进行调整。
本篇文章介绍了如何在 Spring Security 中实现用户注册后自动登录的功能。通过这个功能,可以提高用户体验,减少不必要的操作。