Skip to content
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

6주차 과제 - 로그인 구현하기 #70

Merged
merged 28 commits into from
Oct 3, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
50766c1
Controller , Service 주석 작성
jdalma Sep 5, 2022
6974c98
SessionController login메소드 추가
jdalma Sep 13, 2022
3f6ec78
jwtUtil 추가
jdalma Sep 13, 2022
e500054
InvalidTokenException advice 추가
jdalma Sep 13, 2022
a3bb4f6
상품 등록 시 JWT 및 사용자 확인
jdalma Sep 13, 2022
6caff11
findUser public으로 변경
jdalma Sep 13, 2022
c32ae97
ProductController 테스트 코드 작성
jdalma Sep 13, 2022
df8f01e
JwtUtil 테스트 코드 작성
jdalma Sep 13, 2022
a1ecba0
JwtUtil null 체크 숨기기
jdalma Sep 14, 2022
93ff275
JwtUtil 주석, 테스트 코드 추가
jdalma Sep 14, 2022
2c04eae
ddl-auto create로 수정
jdalma Sep 14, 2022
90f9e60
ProductController 테스트 코드 수정
jdalma Sep 14, 2022
a8d90b9
JwtUtil 테스트 코드 수정
jdalma Sep 14, 2022
05db189
AuthenticationService tokenValidation메소드 추가
JwtUtil 메소드 추가 및 수정
jdalma Sep 14, 2022
7efccfe
decode메소드 검증 부분 수정
jdalma Sep 15, 2022
c833de7
JwtUtil.encode() 테스트 코드 수정
jdalma Sep 15, 2022
c793d25
Session 응답 DTO 추가
jdalma Sep 15, 2022
7930ef9
Session spec 사용자 이메일 수정
jdalma Sep 15, 2022
a64d3c4
로그인 시 사용자 email , password를 확인하여 사용자 검증 및 JWT 반환 추가
jdalma Sep 15, 2022
324f9db
final 선언 및 스코프 줄이기
jdalma Sep 16, 2022
042eaaa
빈 검증 실패 시 에러 메시지 추가
jdalma Sep 16, 2022
ea2588a
수정 및 ExceptionHandler 테스트 코드 추가
jdalma Sep 16, 2022
0699e11
JwtUtil decode 유효성 검사 수정
jdalma Sep 17, 2022
1f1b99f
Product 경로 인증 인터셉터 추가
jdalma Sep 17, 2022
1888b60
UserLoginValidator 임시 추가
jdalma Sep 17, 2022
522ac8f
Update app/src/main/java/com/codesoom/assignment/application/Authenti…
jdalma Sep 18, 2022
7760d3f
AuthenticationService 구현 숨기기
jdalma Sep 18, 2022
5cb2b86
인터페이스 추가
jdalma Sep 18, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.codesoom.assignment.application;

import com.codesoom.assignment.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class AuthenticationService {

private final JwtUtil jwtUtil;

public AuthenticationService(JwtUtil jwtUtil) {
this.jwtUtil = jwtUtil;
}

public String login(){
return jwtUtil.encode(1L);
}

public Claims parseToken(String token) {
return jwtUtil.decode(token);
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JwtUtil 을 직접 사용하는 것과 비교해서 AuthenticationService 를 쓰는 것은 어떠한 장점이 있을까요?!!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

인증JWT 기능에 대한 관심사가 분리되어 있기 때문에 Service가 인증에 대한 책임을 잘 맡으면 다른 도메인 컨트롤러에서도 유용하게 사용할 수 있을 것 같습니다 ㅎㅎ

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋아요! 하지만 그렇다면! Claims 를 리턴하면 JWT를 명시하게 되는 것이 될거에요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 컨트롤러는 AuthenticationService.tokenValidation(String token)을 호출하게만 했고 서비스는 JWT의 존재는 모르게 userId만 받아서 사용자를 찾게만 해봤습니다.
말씀대로 Claims는 JwtUtil에서만 사용하도록 했습니다.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.codesoom.assignment.errors;

public class InvalidTokenException extends RuntimeException {
public InvalidTokenException(String token) {
super("Invalid token : " + token);
}
}
46 changes: 46 additions & 0 deletions app/src/main/java/com/codesoom/assignment/utils/JwtUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.codesoom.assignment.utils;

import com.codesoom.assignment.errors.InvalidTokenException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SignatureException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.security.Key;

@Component
public class JwtUtil {

private final Key key;

public JwtUtil(@Value("${jwt.secret}") String secret){
key = Keys.hmacShaKeyFor(secret.getBytes());
}

public String encode(Long userId){
return Jwts.builder()
.claim("userId" , userId)
.signWith(key)
.compact();
}

public Claims decode(String token) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

예외를 던지는 부분을 주석을 잘 남겨주시면 좋겠어요!

if(token == null || token.isBlank()){
throw new InvalidTokenException(token);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어쩌면 XXX.isBlank(token) 이런 함수로 대체할 수 있을 것 같아요!
객체의 메소드를 호출하는 것과 비교해서 위 코드의 장점은 null 체크를 숨기고 무엇을 하는지만 코드에 보이도록 할 수 있다는 거에요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spring의 StringUtils로 대체해봤습니다

try{
return Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token)
.getBody();
}catch(SignatureException e){
throw new InvalidTokenException(token);
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.codesoom.assignment.applcation;

import com.codesoom.assignment.application.AuthenticationService;
import com.codesoom.assignment.utils.JwtUtil;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.*;

class AuthenticationServiceTest {

private AuthenticationService service;
private final String SECRET = "12345678901234567890123456789012";

@BeforeEach
void setUp() {
JwtUtil jwtUtil = new JwtUtil(SECRET);
service = new AuthenticationService(jwtUtil);
}

@Nested
@DisplayName("")
class Describe_{

@Nested
@DisplayName("")
class Context_{

@Test
@DisplayName("")
void It_(){
String accessToken = service.login();

assertThat(accessToken).contains(".xxxx");
}
}
}
}