[ ] 닉네임, 비밀번호, 비밀번호 확인을 request에서 전달받기
[ ] 닉네임은 최소 3자 이상, 알파벳 대소문자(az, AZ), 숫자(0~9)로 구성하기
[ ] 비밀번호는 최소 4자 이상이며, 닉네임과 같은 값이 포함된 경우 회원가입에 실패로 만들기
[ ] 비밀번호 확인은 비밀번호와 정확하게 일치하기
[ ] 데이터베이스에 존재하는 닉네임을 입력한 채 회원가입 버튼을 누른 경우 "중복된 닉네임입니다." 라는 에러메세지를 response에 포함하기
[ ] 닉네임, 비밀번호를 request에서 전달받기
[ ] 로그인 버튼을 누른 경우 닉네임과 비밀번호가 데이터베이스에 등록됐는지 확인한 뒤, 하나라도 맞지 않는 정보가 있다면 "닉네임 또는 패스워드를 확인해주세요."라는 에러 메세지를 response에 포함하기
[ ] 로그인 성공 시, 로그인에 성공한 유저의 정보를 JWT를 활용하여 클라이언트에게 Cookie로 전달하기
이걸 먼저 시도해 봐야 하는데,
우선 닉네임과 비밀번호를 받는거니까
package com.example.demo.model
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.Table
@Entity
@Table(name = "member")
class Member(
@Column(name = "nick_name" , nullable = false, unique = true)
var nickName: String,
@Column(name = "password" , nullable = false)
var password: String,
)
이렇게 닉네임과 비번을 입력하게 하고
interface MemberRepository : JpaRepository<Member, Long> {
fun findByNickName(nickname: String): Member?
fun existsByNickName(nickName: String): Boolean
}
리포지터리는 이렇게 만든다. 위에 것은 닉네임을 찾는것이고 밑은 닉네임이 아닐경우를 의미하고 이건 서비스임플에 연결된다.
package com.example.demo.dto
data class LoginResponse(
val accessToken: String
)
이걸로 로그인시 토큰을 받고
data class MemberResponse(
val nickname: String,
val email: String
)
이렇게 닉네임과 이메일을 받을수있게 한다.
data class LoginRequest(
@Schema(description = "nickName은 3자이상, 대소문자와 숫자로만 이루어져야 합니다", example = "Aa23")
val nickName: String,
@Schema(description = "비밀번호는 4자 이상, 닉네임과 같으면 회원가입 실패", example = "1234")
val password: String,
@Schema(description = "비밀번호 확인, 비밀번호와 일치해야 합니다", example = "1234")
val passwordConfirm: String
)
그리고 로그인시 닉네임, 비번, 비번 확인을 하라 했으니 이렇게?
data class SignUpRequest(
@Schema(description = "memberName은 3자이상, 대소문자와 숫자로만 이루어져야 합니다", example = "Aa23")
@field:Size(min = 3, message = "닉네임은 최소 3자 이상이어야 합니다.")
@field:Pattern(regexp = "^[a-zA-Z0-9]*\$", message = "닉네임은 알파벳 대소문자와 숫자로만 이루어져야 합니다.")
val nickName: String,
@Schema(description = "비밀번호는 4자 이상, 닉네임과 같으면 회원가입 실패", example = "1234")
@field:Size(min = 4, message = "비밀번호는 최소 4자 이상이어야 합니다.")
val password: String,
@Schema(description = "비밀번호 확인, 비밀번호와 일치해야 합니다", example = "1234")
val passwordConfirm: String
)
이것도 @Schema를 이용해서 제한사항들을 써놓는다.
package com.example.demo.service
import com.example.demo.dto.LoginRequest
import com.example.demo.dto.SignUpRequest
import com.example.demo.model.Member
interface MemberService {
fun signUp(signUpRequest: SignUpRequest): Member
fun login(loginRequest: LoginRequest): Member
}
서비스는 이렇게 해서 로그인과 회원가입을 처리하고
import com.example.demo.dto.LoginRequest
import com.example.demo.dto.SignUpRequest
import com.example.demo.model.Member
import com.example.demo.repository.MemberRepository
import org.springframework.stereotype.Service
@Service
class MemberServiceImpl(
private val memberRepository: MemberRepository
): MemberService {
override fun signUp(signUpRequest: SignUpRequest): Member {
if (signUpRequest.nickName == signUpRequest.password) {
throw IllegalArgumentException("비밀번호는 닉네임과 같을 수 없습니다.")
}
if (signUpRequest.password != signUpRequest.passwordConfirm) {
throw IllegalArgumentException("비밀번호와 비밀번호 확인이 일치하지 않습니다.")
}
if (memberRepository.existsByNickName(signUpRequest.nickName)) {
throw IllegalArgumentException("이미 존재하는 닉네임입니다.")
}
val newMember = Member(nickName = signUpRequest.nickName, password = signUpRequest.password)
return memberRepository.save(newMember)
}
override fun login(loginRequest: LoginRequest): Member {
val member = memberRepository.findByNickName(loginRequest.nickName)
?: throw IllegalArgumentException("닉네임 또는 패스워드를 확인해주세요.")
if (member.password != loginRequest.password) {
throw IllegalArgumentException("닉네임 또는 패스워드를 확인해주세요.")
}
return member
}
}
이걸로 로그인 버튼을 누른 경우 닉네임과 비밀번호가 데이터베이스에 등록됐는지 확인한 뒤, 하나라도 맞지 않는 정보가 있다면 "닉네임 또는 패스워드를 확인해주세요."라는 에러 메세지를 response에 포함하기를 집어 넣는다 라는걸 충족할수있다.
@RestController
@RequestMapping("/api/members")
class MemberController(
private val memberService: MemberService
) {
@PostMapping("/signup")
fun signUp(@RequestBody signUpRequest: SignUpRequest): ResponseEntity<Member> {
val member = memberService.signUp(signUpRequest)
return ResponseEntity.ok(member)
}
@PostMapping("/login")
fun login(@RequestBody loginRequest: LoginRequest): ResponseEntity<Any> {
return try {
val member = memberService.login(loginRequest)
ResponseEntity.ok(member)
} catch (e: IllegalArgumentException) {
ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.message)
}
}
}
컨트롤러는 이렇게 해서 리퀘스트에서 비번, 닉네임을 받고 가입과 로그인을 행한다. 그리고 ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.message) 이거로 에러메시지를 보낸다.