-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature] - 자체 회원 가입과 로그인 구현 #234
Changes from 20 commits
7241333
92b8216
e4bc915
55a8b0b
7cba989
5f21841
931a226
6f800d5
96b6efb
d3b252f
b538714
b4df94f
1371e7d
f9e1a2d
fa9b228
4504162
94373b4
668c4ff
fbefa2c
8cf1d35
0501f4b
6d4a10a
729795a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package kr.touroot.authentication.dto.request; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import jakarta.validation.constraints.Email; | ||
import jakarta.validation.constraints.NotBlank; | ||
|
||
public record LoginRequest( | ||
@Schema(description = "사용자 이메일", example = "email@gmail.com") | ||
@NotBlank(message = "이메일은 비어있을 수 없습니다.") | ||
String email, | ||
@Schema(description = "사용자 비밀번호", example = "@testpassword1234") | ||
@NotBlank(message = "비밀번호는 비어있을 수 없습니다.") | ||
String password | ||
) { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package kr.touroot.authentication.infrastructure; | ||
|
||
import java.math.BigInteger; | ||
import java.security.MessageDigest; | ||
import java.security.NoSuchAlgorithmException; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class PasswordEncryptor { | ||
|
||
public static final int HEXADECIMAL = 16; | ||
|
||
public String encrypt(String password) { | ||
try { | ||
MessageDigest md = MessageDigest.getInstance("SHA-512"); | ||
|
||
byte[] message = md.digest(password.getBytes()); | ||
BigInteger number = new BigInteger(1, message); | ||
|
||
return number.toString(HEXADECIMAL); | ||
} catch (NoSuchAlgorithmException exception) { | ||
throw new RuntimeException(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -95,7 +95,7 @@ public String copyImageToPermanentStorage(String imageUrl) { | |
|
||
private void validateS3Path(String imageKey) { | ||
if (!imageKey.startsWith(imageBaseUri + temporaryStoragePath)) { | ||
throw new BadRequestException("이미지 url 형식이 잘못되었습니다."); | ||
throw new BadRequestException("S3 이미지 url 형식이 잘못되었습니다."); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 굳굳 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 훨씬 좋아졌네요! 감사합니다!! |
||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package kr.touroot.member.controller; | ||
|
||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.media.Content; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import jakarta.validation.Valid; | ||
import java.net.URI; | ||
import kr.touroot.global.exception.dto.ExceptionResponse; | ||
import kr.touroot.member.dto.request.MemberRequest; | ||
import kr.touroot.member.service.MemberService; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@Tag(name = "사용자") | ||
@RequiredArgsConstructor | ||
@RestController | ||
@RequestMapping("/api/v1/members") | ||
public class MemberController { | ||
|
||
private final MemberService memberService; | ||
|
||
@Operation(summary = "회원 가입") | ||
@ApiResponses(value = { | ||
@ApiResponse( | ||
responseCode = "201", | ||
description = "요청이 정상적으로 처리되었을 때" | ||
), | ||
@ApiResponse( | ||
responseCode = "400", | ||
description = "요청 Body에 올바르지 않은 값이 전달되었을 때", | ||
content = @Content(schema = @Schema(implementation = ExceptionResponse.class)) | ||
), | ||
}) | ||
@PostMapping | ||
public ResponseEntity<Void> createMember(@Valid @RequestBody MemberRequest request) { | ||
Long id = memberService.createMember(request); | ||
|
||
return ResponseEntity.created(URI.create("/api/v1/members/" + id)) | ||
.build(); | ||
Comment on lines
+45
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그냥 질문) 반환한 members uri는 어떻게 쓰이나용 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 프론트엔드 분들이 끝의 id를 활용하거나 단순히 몇 번째 멤버가 잘 생성되었는가(어디에 자원이 위치하는가)에 대한 메타데이터 용도이기도 합니다! |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package kr.touroot.member.domain; | ||
|
||
public enum LoginType { | ||
KAKAO, DEFAULT | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package kr.touroot.member.dto.request; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import jakarta.validation.constraints.Email; | ||
import jakarta.validation.constraints.NotBlank; | ||
import kr.touroot.member.domain.LoginType; | ||
import kr.touroot.member.domain.Member; | ||
|
||
public record MemberRequest( | ||
@Schema(description = "사용자 이메일", example = "email@gmail.com") | ||
@NotBlank(message = "이메일은 비어있을 수 없습니다.") | ||
String email, | ||
@Schema(description = "사용자 비밀번호", example = "@testpassword1234") | ||
@NotBlank(message = "비밀번호는 비어있을 수 없습니다.") | ||
String password, | ||
@Schema(description = "사용자 닉네임", example = "뚜리") | ||
@NotBlank(message = "닉네임은 비어있을 수 없습니다.") | ||
String nickname, | ||
@Schema(description = "사용자 프로필 사진 URL", example = "S3 이미지 URL") | ||
@NotBlank(message = "프로필 사진 URL은 비어있을 수 없습니다.") | ||
String profileImageUrl | ||
Comment on lines
+20
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 프사를 설정하지 않는 상남자일 경우 default url을 넣는건 백에서 따로 처리 안해도 되는 건가욤 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 요것도 고민해볼 부분인데, 저희 default 이미지 url이 있다면 그걸로 지정해줘도 좋을 것 같아요. |
||
) { | ||
|
||
public Member toMember(String password) { | ||
return new Member(email, password, nickname, profileImageUrl, LoginType.DEFAULT); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,16 @@ | ||
package kr.touroot.member.repository; | ||
|
||
import java.util.Optional; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import kr.touroot.member.domain.Member; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface MemberRepository extends JpaRepository<Member, Long> { | ||
|
||
Optional<Member> findByKakaoId(Long kakaoId); | ||
|
||
Optional<Member> findByEmailAndPassword(String email, String password); | ||
|
||
Optional<Member> findByEmail(String email); | ||
|
||
Optional<Object> findByNickname(String nickname); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그냥 제안) 위를
kakaoLogin()
으로 하고 일반 로그인을login()
으로 하면 어떨까요? 뭔가 디폴트가 뭐지? 싶을 수도 있을 것 같은There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
동의합니다! 모호한 메소드 네이밍이었네요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저도 같은 생각..!