TIL

JPA - 회원가입 로그인

haseung22 2024. 10. 17. 11:27

저번 포스팅에 올렸던  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 토큰을 추가해주고 로그인한 유저 정보를 반환해준다.

 

데이터베이스에도 잘 들어간걸 볼 수있다.