2024. 4. 15. 20:56ㆍ[Way to PM] 백 엔드
Over View
스프링 시큐리티를 통해 인증 기능을 구현한다면, 현재 인증된 유저(로그인한 유저)의 정보가 필요한 경우가 있습니다. 유저 정보(인증 객체)를 가져올 수 있는 방법은 메서드, 인터페이스, 어노테이션 등 다양하게 있습니다.
1. 메서드로 구현하기
private User getAuthenticatedUser() {
String username = SecurityContextHolder.getContext().getAuthentication().getName();
return userRepository.findByEmail(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found: " + username));
}
유저정보가 필요한 서비스레이어에 UserRepository를 DI하고 SecurityContextHolder에 load된 인증 정보를 가져올 수 있습니다. 여기서 getName()메서드를 통해 얻는 값은 바로,
.usernameParameter("email")
시큐리티 설정에서 usernameParameter로 받기로한 값을 가져옵니다. 이번에 구축한 프로젝트에서는 email이 unique한 값이었기 때문에 usernameParameter를 email로 받았습니다.
여기서 username은 User엔티티에서 임의로 설정한 Username컬럼이 아니라(이 경우엔 유저가 사용하는 유저네임), 시큐리티 인증과정에서 자격증명에 사용되는 정보 자체를 username이라고 합니다. 이 값은 시큐리티 설정을 통해 위와같이 커스텀해서 지정할 수 있습니다.
2. 어노테이션으로 구현하기
@GetMapping("/api/meeting/{meetingId}")
public MeetingResponseDto getOneMeeting(@PathVariable Long meetingId, @AuthenticationPrincipal User user) {
return meetingService.getOneMeeting(meetingId, user);
실제로 프로젝트에서 구현한 모임글의 Read API입니다. @AuthenticationPrincipal을 통해 User 객체를 인자로 받을 수 있습니다. SecurityContextHolder에 담긴 유저 정보를 바로 인자로 받을 수 있기 때문에 서비스레이어에 메서드를 구현할 필요가 없습니다.
3. 인터페이스로 구현하기
@PostMapping("/changePassword")
public String changePassword(@RequestParam("password") String password,
@RequestParam("newPassword") String newPassword,
Principal principal,
HttpServletRequest request,
HttpServletResponse response,
Model model) {
String email = principal.getName();
User user = userService.findByEmail(email);
if (user != null && userService.checkPassword(user, password)) {
// 현재 비밀번호가 일치하는 경우, 새로운 비밀번호로 변경 처리
userService.resetPassword(user, newPassword);
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null) {
new SecurityContextLogoutHandler().logout(request, response, auth);
}
return "redirect:/login";
} else {
model.addAttribute("error", "현재 비밀번호가 올바르지 않습니다.");
return "myPage";
}
}
또한 이처럼 Principal 인터페이스를 import 해서 변수에 Principal 객체를 주입할 수 있습니다. Principal은 Authentication 객체의 일부로서 사용자의 식별정보가 들어있습니다.(getName()으로 가져올 수 있는 값)
위에서 설명했듯이 이 케이스에선 usernameParameter로 받은 email값을 식별 정보로 가지고 있기 때문에 해당하는 값을 반환받을 수 있습니다.
'[Way to PM] 백 엔드' 카테고리의 다른 글
[Way to PM] 백 엔드(스프링부트) - 연관 관계 매핑 (0) | 2024.03.26 |
---|---|
[Way to PM] 백엔드(스프링부트) - CRUD 테스트 코드 (0) | 2024.03.22 |
[Way to PM] 백엔드(스프링부트) - JPA Update Method (0) | 2024.03.20 |
[Way to PM] 백엔드(스프링부트) - .yml 파일에 MyBatis 적용 시 띄어쓰기의 중요성 (0) | 2024.03.09 |
[Way to PM] 백엔드(스프링부트) - MVC (3) | 2024.03.09 |