코드 그라데이션
JWT 예제 구현 (10) Response 시 DTO를 통해서만 응답하도록 변경 본문
Controller
UserController
@RequiredArgsConstructor
@RestController
@RequestMapping("/api")
public class UserController {
private final UserService userService;
/**
* 사용자 등록을 처리하는 엔드포인트.
*
* @param userDto 등록할 사용자 정보를 포함한 UserDto 객체
* @return ResponseEntity<UserDto> 등록된 사용자 정보를 포함한 ResponseEntity
*/
// 여기 변경
@PostMapping("/signup")
public ResponseEntity<UserDto> signup(@Valid @RequestBody UserDto userDto) {
return ResponseEntity.ok(userService.signup(userDto));
}
/**
* 현재 사용자의 정보를 조회하는 엔드포인트.
*
* @param request HttpServletRequest 객체
* @return ResponseEntity<UserDto> 현재 사용자 정보를 포함한 ResponseEntity
*/
// 여기 변경
@GetMapping("/user")
@PreAuthorize("hasAnyRole('USER', 'ADMIN')")
public ResponseEntity<UserDto> getMyUserInfo(HttpServletRequest request) {
return ResponseEntity.ok(userService.getMyUserWithAuthorities());
}
/**
* 리디렉션 테스트를 위한 엔드포인트.
*
* @param response HttpServletResponse 객체
* @throws IOException 입출력 예외 발생 시
*/
@PostMapping("/test-redirect")
public void testRedirect(HttpServletResponse response) throws IOException {
response.sendRedirect("/api/user");
}
/**
* 특정 사용자의 정보를 조회하는 엔드포인트.
*
* @param username 조회할 사용자의 이름
* @return ResponseEntity<UserDto> 조회된 사용자 정보를 포함한 ResponseEntity
*/
// 여기 변경
@GetMapping("/user/{username}")
@PreAuthorize("hasAnyRole('ADMIN')")
public ResponseEntity<UserDto> getUserInfo(@PathVariable String username) {
return ResponseEntity.ok(userService.getUserWithAuthorities(username));
}
}
전체적으로 반환형 User -> UserDto
DTO
AuthorityDto 새로 생성
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AuthorityDto {
private String authorityName;
}
UserDto에 추가
import com.fasterxml.jackson.annotation.JsonProperty;
import inflearn.freejwt.entity.User;
import lombok.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.Set;
import java.util.stream.Collectors;
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UserDto {
@NotNull
@Size(min = 3, max = 50)
private String username;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@NotNull
@Size(min = 3, max = 100)
private String password;
@NotNull
@Size(min = 3, max = 50)
private String nickname;
// 추가: UserDto 클래스에 있는 authorityDtoSet 필드를 선언.
private Set<AuthorityDto> authorityDtoSet;
// 정적 메서드인 from(User user)를 정의.
public static UserDto from(User user) {
// 만약 입력으로 주어진 user가 null이면 null을 반환.
if (user == null) return null;
// UserDto 객체를 빌더 패턴을 사용하여 생성.
return UserDto.builder()
// User 객체의 username 값을 UserDto 객체의 username에 설정.
.username(user.getUsername())
// User 객체의 nickname 값을 UserDto 객체의 nickname에 설정.
.nickname(user.getNickname())
// User 객체의 authorities (권한) 집합을 스트림으로 변환한 후,
// 각 권한을 AuthorityDto 객체로 매핑하여 새로운 Set으로 수집.
.authorityDtoSet(user.getAuthorities().stream()
.map(authority -> AuthorityDto.builder().authorityName(authority.getAuthorityName()).build())
.collect(Collectors.toSet()))
// UserDto 객체를 빌드하여 반환합니다.
.build();
}
}
User에 @JsonIgnore 어노테이션 삭제
UserService
import inflearn.freejwt.dto.UserDto;
import inflearn.freejwt.entity.Authority;
import inflearn.freejwt.entity.User;
import inflearn.freejwt.exception.DuplicateMemberException;
import inflearn.freejwt.repository.UserRepository;
import inflearn.freejwt.util.SecurityUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import java.util.Optional;
@RequiredArgsConstructor
@Service
public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
/**
*
* @param userDto
* @return
*/
@Transactional
public UserDto signup(UserDto userDto) {
if (userRepository.findOneWithAuthoritiesByUsername(userDto.getUsername()).orElse(null) != null) {
throw new DuplicateMemberException("이미 가입되어 있는 유저입니다."); // 변경
}
// 권한 정보 생성
Authority authority = Authority.builder()
.authorityName("ROLE_USER")
.build();
// 유저 정보 생성
User user = User.builder()
.username(userDto.getUsername())
.password(passwordEncoder.encode(userDto.getPassword()))
.nickname(userDto.getNickname())
.authorities(Collections.singleton(authority))
.activated(true)
.build();
// 저장
return UserDto.from(userRepository.save(user));
}
/**
*
* @param username
* @return
*/
@Transactional(readOnly = true)
public UserDto getUserWithAuthorities(String username) {
return UserDto.from(userRepository.findOneWithAuthoritiesByUsername(username).orElse(null));
}
/**
*
* @return
*/
@Transactional(readOnly = true)
public UserDto getMyUserWithAuthorities() {
return UserDto.from(SecurityUtil.getCurrentUsername().flatMap(userRepository::findOneWithAuthoritiesByUsername).orElse(null));
}
}
반환형 : Optional<User> -> UserDto
리턴 변경
728x90
'Spring > Security' 카테고리의 다른 글
JWT 예제 구현 (11) 버전 2.7.2 업데이트, 그래들 업데이트,RestResponseExceptionHandler 수정 (1) | 2023.12.21 |
---|---|
[중간점검] 또 여기까지 전체 코드 정리 / 버전 2.5.3 (0) | 2023.12.20 |
JWT 예제 구현 (9) Exception 세분화, 리다이렉트 수정, Response 로직 변경, 리다이렉트 테스트 추가 (1) | 2023.12.18 |
JWT 예제 구현 (8) 예외처리 로직 추가, Exception(핸들러) 추가, 버전 2.53 업그레이드 등 (0) | 2023.12.16 |
[중간점검] JWT 2.41 버전 구현 로직 완성 코드 (0) | 2023.12.15 |
Comments