저번 포스팅에 올렸던 JwtUti를 이용하여 회원가입과 로그인을 구현하였다.
1. 엔티티 생성
일정과 일정 담당유저와의 연관관계를 맺으라는 요구사항이 있어 OneToMany를 이용하여 1:N관계를 맺었다.
@Entity
@Getter
@Table(name = "user")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User extends AuditingDate {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private String userName;
@Column(nullable = false)
@Enumerated(EnumType.STRING)
private UserRole role;
@OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE)
private List<Todo> todo = new ArrayList<>();
@OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE)
private List<Manager> manager = new ArrayList<>();
public static User from(String email, String password, String userName, UserRole role) {
User user = new User();
user.init(email,password,userName,role);
return user;
}
private void init(String email, String password, String userName, UserRole role) {
this.email = email;
this.password = password;
this.userName = userName;
this.role = role;
}
public void modify(String userName) {
this.userName = userName;
}
1-2 UserRole
일반유저와 관리자 권한을 나누기 위하여 Role enum도 만든다.
package com.sparta.todo.domain.user.entity;
public enum UserRole {
// 일반유저
USER("ROLE_USER"),
// 관리자
ADMIN("ROLE_ADMIN");
private final String authority;
UserRole(String authority) {
this.authority = authority;
}
public String getAuthority() {
return this.authority;
}
}
2. DTO
Validation을 이용하여 입력값들을 검증하였다.
2-1 JoinRequestDto
package com.sparta.todo.domain.user.dto;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import lombok.Getter;
@Getter
public class JoinRequestDto {
@Email
private String email;
@Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,15}$",
message = "비밀번호는 최소 8자리 이상, 영문, 숫자, 특수문자를 1자 이상 포함되어야 합니다.")
@NotBlank
private String password;
@NotBlank
private String userName;
private String adminToken = "";
}
2-2 LoginRequestDto
package com.sparta.todo.domain.user.dto;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
@Getter
public class LoginRequestDto {
@NotBlank(message = "이메일을 입력해야합니다.")
private String email;
@NotBlank(message = "password 입력해주세요.")
private String password;
}
3. UserService
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final HttpServletResponse httpServletResponse;
private final PasswordEncoder passwordEncoder;
private final JwtUtil jwtUtil;
private final String adminToken = "sksmsrhksflwkdla";
@Transactional
public String join(JoinRequestDto joinRequestDto) {
//패스워드 암호화
String password = passwordEncoder.encode(joinRequestDto.getPassword());
String email = joinRequestDto.getEmail();
Optional<User> checkUser = userRepository.findByEmail(email);
if(checkUser.isPresent()) throw new CustomException(ErrorCode.EMAIL_DUPLICATION);
UserRole role = UserRole.USER;
// 입력받은 어드민토큰 값이 미리 설정해둔 토큰값과 같다면 관리자 권한 부여
if(joinRequestDto.getAdminToken().equals(adminToken)) role = UserRole.ADMIN;
User user = User.from(email,password,joinRequestDto.getUserName(),role);
userRepository.save(user);
return jwtUtil.createAccessToken(user.getId(), user.getRole().getAuthority());
}
public UserResponseDto login(LoginRequestDto loginRequestDto){
Optional<User> checkUser = userRepository.findByEmail(loginRequestDto.getEmail());
if(checkUser.isEmpty()) throw new CustomException(ErrorCode.NOT_MATCH_LOGIN);
User findUser = checkUser.get();
if(!passwordEncoder.matches(loginRequestDto.getPassword(), findUser.getPassword())) throw new CustomException(ErrorCode.NOT_MATCH_LOGIN);
String token = jwtUtil.createAccessToken(findUser.getId(), findUser.getRole().getAuthority());
jwtUtil.addJwtToHeader(httpServletResponse,token);
return new UserResponseDto(findUser);
}
}
포스트맨으로 테스트 해보기
회원가입
회원가입시에는 토큰을 생성 후 토큰을 그대로 반환해주도록했다.
로그인
로그인 성공시에는 헤더에 Jwt 토큰을 추가해주고 로그인한 유저 정보를 반환해준다.
데이터베이스에도 잘 들어간걸 볼 수있다.
'TIL' 카테고리의 다른 글
REST, REST API, RESTful (2) | 2024.10.21 |
---|---|
JPA - 일정관리 앱 만들기 (1) | 2024.10.17 |
JPA - JWT와 필터 구현하기 (1) | 2024.10.16 |
영속성 컨텍스트 (1) | 2024.10.16 |
페이징 조회 - Pageble / PageRequest (0) | 2024.10.15 |