-
Notifications
You must be signed in to change notification settings - Fork 3
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
feat: 회원 생성 및 로그인 응답 기능 구현 #47
Changes from 50 commits
2cb3959
3c119f8
729d7d2
9cbfc2e
e056905
0dc50e4
233661a
18f3496
a1e7533
b5163eb
9c10d45
92cb531
a7291a8
47ef3ea
5a76a50
ab0063d
ab0b0ab
dff5e2e
31407ab
448011e
c421394
40cac6f
36a64b1
1eb8eb4
5ef8308
82925fa
95bea5d
7e53464
41b234b
dffed00
5c32df9
436dbdc
5b94df4
9995d28
f58059b
d1db0e4
7862353
dbf9488
5aa6cc0
cf030fc
f706306
64d1609
672840e
0759ebb
9080613
00b1fe0
42ddbd6
4b00b42
b9b90f2
3294470
dafef37
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,43 @@ | ||
package com.moabam.api.application; | ||
|
||
import java.util.Base64; | ||
|
||
import org.json.JSONObject; | ||
import org.springframework.stereotype.Service; | ||
|
||
import com.moabam.global.config.TokenConfig; | ||
import com.moabam.global.error.exception.UnauthorizedException; | ||
import com.moabam.global.error.model.ErrorMessage; | ||
|
||
import io.jsonwebtoken.ExpiredJwtException; | ||
import io.jsonwebtoken.Jwts; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class JwtAuthenticationService { | ||
|
||
private final TokenConfig tokenConfig; | ||
|
||
public boolean isTokenValid(String token) { | ||
try { | ||
Jwts.parserBuilder() | ||
.setSigningKey(tokenConfig.getKey()) | ||
.build() | ||
.parseClaimsJwt(token); | ||
return true; | ||
} catch (ExpiredJwtException expiredJwtException) { | ||
return false; | ||
} catch (Exception exception) { | ||
throw new UnauthorizedException(ErrorMessage.AUTHENTICATIE_FAIL); | ||
} | ||
} | ||
|
||
public String parseEmail(String token) { | ||
String claims = token.split("\\.")[1]; | ||
String decodeClaims = new String(Base64.getDecoder().decode(claims)); | ||
JSONObject jsonObject = new JSONObject(decodeClaims); | ||
|
||
return (String)jsonObject.get("id"); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.moabam.api.application; | ||
|
||
import java.util.Date; | ||
|
||
import org.springframework.stereotype.Service; | ||
|
||
import com.moabam.global.config.TokenConfig; | ||
|
||
import io.jsonwebtoken.Jwts; | ||
import io.jsonwebtoken.SignatureAlgorithm; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class JwtProviderService { | ||
|
||
private final TokenConfig tokenConfig; | ||
|
||
public String provideAccessToken(long id) { | ||
return generateToken(id, tokenConfig.getAccessExpire()); | ||
} | ||
|
||
public String provideRefreshToken(long id) { | ||
return generateToken(id, tokenConfig.getRefreshExpire()); | ||
} | ||
|
||
private String generateToken(long id, long expireTime) { | ||
Date issueDate = new Date(); | ||
Date expireDate = new Date(issueDate.getTime() + expireTime); | ||
|
||
return Jwts.builder() | ||
.setHeaderParam("alg", "HS256") | ||
.setHeaderParam("typ", "JWT") | ||
.setIssuer(tokenConfig.getIss()) | ||
.setIssuedAt(issueDate) | ||
.setExpiration(expireDate) | ||
.claim("id", id) | ||
.signWith(tokenConfig.getKey(), SignatureAlgorithm.HS256) | ||
.compact(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,22 @@ | ||
package com.moabam.api.application; | ||
|
||
import static com.moabam.global.common.constant.GlobalConstant.*; | ||
import static com.moabam.global.error.model.ErrorMessage.*; | ||
|
||
import java.security.SecureRandom; | ||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
import org.apache.commons.lang3.RandomStringUtils; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import com.moabam.api.domain.entity.Member; | ||
import com.moabam.api.domain.repository.MemberRepository; | ||
import com.moabam.api.domain.repository.MemberSearchRepository; | ||
import com.moabam.api.dto.AuthorizationTokenInfoResponse; | ||
import com.moabam.api.dto.LoginResponse; | ||
import com.moabam.api.dto.MemberMapper; | ||
import com.moabam.global.error.exception.NotFoundException; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
|
@@ -27,6 +34,34 @@ public Member getById(Long memberId) { | |
.orElseThrow(() -> new NotFoundException(MEMBER_NOT_FOUND)); | ||
} | ||
|
||
public boolean isExistMember(Long memberId) { | ||
return memberRepository.existsById(memberId); | ||
} | ||
|
||
@Transactional | ||
public LoginResponse login(AuthorizationTokenInfoResponse authorizationTokenInfoResponse) { | ||
Optional<Member> member = memberRepository.findBySocialId(authorizationTokenInfoResponse.id()); | ||
|
||
if (member.isEmpty()) { | ||
Member signUpMember = signUp(authorizationTokenInfoResponse.id()); | ||
return MemberMapper.toLoginResponse(signUpMember.getId(), true); | ||
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. R: 개행 ~! |
||
} | ||
|
||
return MemberMapper.toLoginResponse(member.get().getId()); | ||
} | ||
|
||
private Member signUp(long socialId) { | ||
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. R: 여기두 long Long ~! |
||
String randomNick = createRandomNickName(); | ||
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. R: randomNickName 쩜..! |
||
Member member = MemberMapper.toMember(socialId, randomNick); | ||
|
||
return memberRepository.save(member); | ||
} | ||
|
||
private String createRandomNickName() { | ||
return RandomStringUtils.random(RANDOM_NICKNAME_SIZE, 0, 0, true, true, null, | ||
new SecureRandom()); | ||
} | ||
|
||
public Member getManager(Long roomId) { | ||
return memberSearchRepository.findManager(roomId) | ||
.orElseThrow(() -> new NotFoundException(MEMBER_NOT_FOUND)); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,7 +40,7 @@ public class Member extends BaseTimeEntity { | |
private Long id; | ||
|
||
@Column(name = "social_id", nullable = false, unique = true) | ||
private String socialId; | ||
private long socialId; | ||
|
||
@Column(name = "nickname", nullable = false, unique = true) | ||
private String nickname; | ||
|
@@ -79,11 +79,11 @@ public class Member extends BaseTimeEntity { | |
private LocalDateTime deletedAt; | ||
|
||
@Builder | ||
private Member(Long id, String socialId, String nickname, String profileImage, Bug bug) { | ||
private Member(Long id, long socialId, String nickname, Bug bug) { | ||
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. R: soft delete 방식이기에 primitive 타입이 아닌 Long 타입이 아닐까요 !? |
||
this.id = id; | ||
this.socialId = requireNonNull(socialId); | ||
this.socialId = socialId; | ||
this.nickname = requireNonNull(nickname); | ||
this.profileImage = requireNonNullElse(profileImage, BaseImageUrl.PROFILE_URL); | ||
this.profileImage = BaseImageUrl.PROFILE_URL; | ||
this.bug = requireNonNull(bug); | ||
this.role = Role.USER; | ||
} | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,9 +1,12 @@ | ||||||
package com.moabam.api.domain.repository; | ||||||
|
||||||
import java.util.Optional; | ||||||
|
||||||
import org.springframework.data.jpa.repository.JpaRepository; | ||||||
|
||||||
import com.moabam.api.domain.entity.Member; | ||||||
|
||||||
public interface MemberRepository extends JpaRepository<Member, Long> { | ||||||
|
||||||
Optional<Member> findBySocialId(long id); | ||||||
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.
Suggested change
R: 여기도 재윤님 의견처럼 socialId로 해주세용 |
||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.moabam.api.dto; | ||
|
||
import lombok.Builder; | ||
|
||
@Builder | ||
public record LoginResponse( | ||
Long id, | ||
boolean isSignUp | ||
) { | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.moabam.api.dto; | ||
|
||
import com.moabam.api.domain.entity.Bug; | ||
import com.moabam.api.domain.entity.Member; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.NoArgsConstructor; | ||
|
||
@NoArgsConstructor(access = AccessLevel.PRIVATE) | ||
public final class MemberMapper { | ||
|
||
public static Member toMember(Long id, String nickName) { | ||
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. R: id를 socialId로 ~! |
||
return Member.builder() | ||
.socialId(id) | ||
.nickname(nickName) | ||
.bug(Bug.builder().build()) | ||
.build(); | ||
} | ||
|
||
public static LoginResponse toLoginResponse(Long memberId) { | ||
return LoginResponse.builder() | ||
.id(memberId) | ||
.build(); | ||
} | ||
|
||
public static LoginResponse toLoginResponse(Long memberId, boolean isSignUp) { | ||
return LoginResponse.builder() | ||
.id(memberId) | ||
.isSignUp(isSignUp) | ||
.build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.moabam.global.common.util; | ||
|
||
import jakarta.servlet.http.Cookie; | ||
import lombok.AccessLevel; | ||
import lombok.NoArgsConstructor; | ||
|
||
@NoArgsConstructor(access = AccessLevel.PRIVATE) | ||
public class CookieUtils { | ||
|
||
public static Cookie tokenCookie(String name, String value) { | ||
Cookie cookie = new Cookie(name, value); | ||
cookie.setSecure(true); | ||
cookie.setHttpOnly(true); | ||
cookie.setPath("/"); | ||
|
||
return cookie; | ||
} | ||
} |
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.
R: isExist가 메서드 명이 너무 중복되는 것 같아요.. !