실무 프로젝트로 배우는 Kotlin & Spring/회원 인증 서비스 개발하기

회원가입

webmaster 2022. 12. 14. 00:19
728x90

domain

User

@Table("users")
data class User(
    @Id
    val id: Long? = null,
    @Column
    val email: String,
    @Column
    val password: String,
    @Column
    val username: String,
    @Column
    val profileUrl: String? = null,

    @Column("created_at")
    @CreatedDate
    val createdAt: LocalDateTime? = null,

    @Column("updated_at")
    @LastModifiedDate
    val updatedAt: LocalDateTime? = null,
)
  • User 도메인을 작성한다.

UserRepository

interface UserRepository: CoroutineCrudRepository<User, Long> {
    suspend fun findByEmail(email: String): User?
}
  • coroutine을 사용하므로, coroutineCrudRepository를 상속받아 작성한다.
  • suspend 키워드를 붙여 코루틴임을 명시하고, 코드를 작성한다.

Service

@Service
class UserService(
    private val userRepository: UserRepository,
) {
    suspend fun signUp(signUpRequest: SignUpRequest) {
        with(signUpRequest) {
            userRepository.findByEmail(email)?.let { throw UserExistsException() }
            val user = User(
                email = email,
                password = BCryptUtils.hash(password),
                username = username
            )
            userRepository.save(user)
        }
    }
}

Exception 추가

data class UserExistsException(
    override val message: String = "이미 존재하는 유저입니다"
): ServerException(409, message)

BCryptUtils

object BCryptUtils {
    fun hash(password: String) =
        BCrypt.withDefaults().hashToString(12, password.toCharArray())

    fun verity(password: String, hashedPassword: String) =
        BCrypt.verifyer().verify(password.toCharArray(), hashedPassword).verified //verified 가 반환하는것이 true면 일치, false면 불일치
}

SignupRequest

class SignUpRequest(
    val email: String,
    val password: String,
    val username: String,
) {
}
  • User가 이미 존재할 수도 있으므로, UserExistsException을 추가해, 존재하면 오류가 발생하도록 한다.
  • BCryptUtils를 사용하여 hash() 함수를 통해 암호화된 비밀번호를 verity() 함수를 통해 입력된 password와 DB에 저장된 password가 같은지를 검증한다.

Controller

@RestController
@RequestMapping("/api/v1/users")
class UserController(
    private val userService: UserService,
) {
    @PostMapping("/signup")
    suspend fun signUp(@RequestBody request: SignUpRequest){
        userService.signUp(request)
    }
}
728x90

'실무 프로젝트로 배우는 Kotlin & Spring > 회원 인증 서비스 개발하기' 카테고리의 다른 글

내정보 조회  (0) 2022.12.16
로그인과 로그아웃  (0) 2022.12.15
JWT 기반 인증 구현  (0) 2022.12.13
토큰 기반 인증  (0) 2022.12.13
공통 에러 처리  (0) 2022.12.13