Skip to content

Commit

Permalink
Merge pull request #80 from dev-hooon/feat/#57
Browse files Browse the repository at this point in the history
feat : JWT에 권한을 함께 넣어준다.
  • Loading branch information
kkangh00n authored Jan 9, 2024
2 parents 721e9cc + 3b6d442 commit 0e120f4
Show file tree
Hide file tree
Showing 17 changed files with 115 additions and 40 deletions.
15 changes: 15 additions & 0 deletions src/main/java/com/prgrms/catchtable/common/Role.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.prgrms.catchtable.common;

import static com.prgrms.catchtable.common.exception.ErrorCode.INVALID_INPUT_TYPE;

import com.prgrms.catchtable.common.exception.custom.BadRequestCustomException;
import java.util.Arrays;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

Expand All @@ -11,4 +15,15 @@ public enum Role {
OWNER("ROLE_OWNER");

private final String role;

public static Role of(String type) {
return Arrays.stream(values())
.filter(role -> role.isEqual(type))
.findAny()
.orElseThrow(() -> new BadRequestCustomException(INVALID_INPUT_TYPE));
}

private boolean isEqual(String input) {
return input.equals(this.role);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
@RequiredArgsConstructor
public enum ErrorCode {
NOT_EXIST_MEMBER("존재하지 않는 회원입니다."),
NOT_EXIST_OWNER("존재하지 않는 점주입니다."),
NOT_FOUND_REFRESH_TOKEN("유효하지 않은 RefreshToken입니다."),
TOKEN_EXPIRES("토큰이 만료되었습니다. 다시 로그인 해 주세요."),

Expand All @@ -31,10 +32,9 @@ public enum ErrorCode {
SHOP_NOT_RUNNING("가게가 영업시간이 아닙니다."),
INTERNAL_SERVER_ERROR("내부 서버 오류입니다."),


ALREADY_EXIST_OWNER("이미 존재하는 점주입니다"),
NOT_EXIST_OWNER("해당 아이디의 점주가 존재하지 않습니다."),
BAD_REQUEST_EMAIL_OR_PASSWORD("이메일 혹은 비밀번호를 확인해주세요"),
BAD_REQUEST_INPUT_GENDER_TYPE("성별 타입을 양식대로 입력해주세요");
INVALID_EMAIL_OR_PASSWORD("이메일 혹은 비밀번호를 확인해주세요"),
INVALID_INPUT_TYPE("성별 타입을 양식대로 입력해주세요");

private final String message;
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.prgrms.catchtable.jwt.domain;

import static jakarta.persistence.EnumType.STRING;
import static lombok.AccessLevel.PROTECTED;

import com.prgrms.catchtable.common.Role;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
Expand All @@ -26,10 +29,15 @@ public class RefreshToken {
@Column(name = "email")
private String email;

@Column(name = "role")
@Enumerated(STRING)
private Role role;

@Builder
public RefreshToken(String token, String email) {
public RefreshToken(String token, String email, Role role) {
this.token = token;
this.email = email;
this.role = role;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static com.prgrms.catchtable.common.exception.ErrorCode.TOKEN_EXPIRES;

import com.prgrms.catchtable.common.Role;
import com.prgrms.catchtable.common.exception.custom.BadRequestCustomException;
import com.prgrms.catchtable.jwt.domain.RefreshToken;
import com.prgrms.catchtable.jwt.provider.JwtTokenProvider;
Expand Down Expand Up @@ -48,7 +49,8 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
RefreshToken refreshTokenEntity = refreshTokenService.getRefreshTokenByToken(
refreshToken);
String email = refreshTokenEntity.getEmail();
Token newToken = jwtTokenProvider.createToken(email);
Role role = refreshTokenEntity.getRole();
Token newToken = jwtTokenProvider.createToken(email, role);

((HttpServletResponse) response).setHeader("AccessToken",
newToken.getAccessToken());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.prgrms.catchtable.jwt.provider;


import com.prgrms.catchtable.common.Role;
import com.prgrms.catchtable.jwt.config.JwtConfig;
import com.prgrms.catchtable.jwt.service.JwtUserDetailsService;
import com.prgrms.catchtable.jwt.token.Token;
Expand All @@ -20,18 +21,19 @@
public class JwtTokenProvider {

private final JwtConfig jwtConfig;

private final JwtUserDetailsService jwtUserDetailsService;
private final String JWT_ROLE = "ROLE";

public Token createToken(String email) {
public Token createToken(String email, Role role) {

Claims claims = Jwts.claims().setSubject(email);
claims.put(JWT_ROLE, role.getRole());
Date now = new Date();

String accessToken = createAccessToken(claims, now);
String refreshToken = createRefreshToken(claims, now);

return new Token(accessToken, refreshToken, email);
return new Token(accessToken, refreshToken, email, role);
}

private String createAccessToken(Claims claims, Date now) {
Expand Down Expand Up @@ -73,7 +75,9 @@ public boolean validateToken(String token) {

public Authentication getAuthentication(String token) {
String email = getEmail(token);
UserDetails userDetails = jwtUserDetailsService.loadUserByUsername(email);
Role role = getRole(token);

UserDetails userDetails = jwtUserDetailsService.loadUserByUsername(email, role);
return new UsernamePasswordAuthenticationToken(userDetails, "",
userDetails.getAuthorities());
}
Expand All @@ -87,4 +91,16 @@ private String getEmail(String token) {

return claims.getSubject();
}

private Role getRole(String token) {
Claims claims = Jwts.parserBuilder()
.setSigningKey(jwtConfig.getClientSecret())
.build()
.parseClaimsJws(token)
.getBody();

String role = (String) claims.get(JWT_ROLE);

return Role.of(role);
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
package com.prgrms.catchtable.jwt.service;

import static com.prgrms.catchtable.common.exception.ErrorCode.NOT_EXIST_MEMBER;
import static com.prgrms.catchtable.common.exception.ErrorCode.NOT_EXIST_OWNER;

import com.prgrms.catchtable.common.Role;
import com.prgrms.catchtable.common.exception.custom.NotFoundCustomException;
import com.prgrms.catchtable.member.repository.MemberRepository;
import com.prgrms.catchtable.owner.repository.OwnerRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class JwtUserDetailsService implements UserDetailsService {
public class JwtUserDetailsService {

private final MemberRepository memberRepository;
private final OwnerRepository ownerRepository;

@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
return memberRepository.findMemberByEmail(email)
.orElseThrow(() -> new NotFoundCustomException(NOT_EXIST_MEMBER));
public UserDetails loadUserByUsername(String email, Role role)
throws UsernameNotFoundException {

if (role.equals(Role.MEMBER)) {
return memberRepository.findMemberByEmail(email)
.orElseThrow(() -> new NotFoundCustomException(NOT_EXIST_MEMBER));
} else {
return ownerRepository.findOwnerByEmail(email)
.orElseThrow(() -> new NotFoundCustomException(NOT_EXIST_OWNER));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static com.prgrms.catchtable.common.exception.ErrorCode.NOT_FOUND_REFRESH_TOKEN;

import com.prgrms.catchtable.common.Role;
import com.prgrms.catchtable.common.exception.custom.NotFoundCustomException;
import com.prgrms.catchtable.jwt.domain.RefreshToken;
import com.prgrms.catchtable.jwt.repository.RefreshTokenRepository;
Expand All @@ -19,6 +20,7 @@ public class RefreshTokenService {
@Transactional
public void saveRefreshToken(Token totalToken) {
String email = totalToken.getEmail();
Role role = totalToken.getRole();

if (refreshTokenRepository.existsRefreshTokenByEmail(email)) {
refreshTokenRepository.deleteRefreshTokenByEmail(email);
Expand All @@ -27,6 +29,7 @@ public void saveRefreshToken(Token totalToken) {
RefreshToken newRefreshToken = RefreshToken.builder()
.token(totalToken.getRefreshToken())
.email(email)
.role(role)
.build();

refreshTokenRepository.save(newRefreshToken);
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/com/prgrms/catchtable/jwt/token/Token.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.prgrms.catchtable.jwt.token;

import com.prgrms.catchtable.common.Role;
import lombok.AllArgsConstructor;
import lombok.Getter;

Expand All @@ -12,4 +13,6 @@ public class Token {
private String refreshToken;

private String email;

private Role role;
}
4 changes: 2 additions & 2 deletions src/main/java/com/prgrms/catchtable/member/domain/Gender.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.prgrms.catchtable.member.domain;

import static com.prgrms.catchtable.common.exception.ErrorCode.BAD_REQUEST_INPUT_GENDER_TYPE;
import static com.prgrms.catchtable.common.exception.ErrorCode.INVALID_INPUT_TYPE;

import com.prgrms.catchtable.common.exception.custom.BadRequestCustomException;
import java.util.Arrays;
Expand All @@ -19,7 +19,7 @@ public static Gender of(String input) {
return Arrays.stream(values())
.filter(gender -> gender.isEqual(input))
.findAny()
.orElseThrow(() -> new BadRequestCustomException(BAD_REQUEST_INPUT_GENDER_TYPE));
.orElseThrow(() -> new BadRequestCustomException(INVALID_INPUT_TYPE));
}

private boolean isEqual(String input) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.prgrms.catchtable.member.service;

import com.prgrms.catchtable.common.Role;
import com.prgrms.catchtable.jwt.provider.JwtTokenProvider;
import com.prgrms.catchtable.jwt.service.RefreshTokenService;
import com.prgrms.catchtable.jwt.token.Token;
Expand All @@ -17,10 +18,8 @@
public class MemberService {

private final MemberRepository memberRepository;

private final JwtTokenProvider jwtTokenProvider;

private final RefreshTokenService refreshTokenService;
private final JwtTokenProvider jwtTokenProvider;

@Transactional
public Token oauthLogin(OAuthAttribute attributes) {
Expand All @@ -36,7 +35,7 @@ public Token oauthLogin(OAuthAttribute attributes) {
}

private Token createTotalToken(String email) {
Token totalToken = jwtTokenProvider.createToken(email);
Token totalToken = jwtTokenProvider.createToken(email, Role.MEMBER);
refreshTokenService.saveRefreshToken(totalToken);
return totalToken;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.prgrms.catchtable.owner.service;

import static com.prgrms.catchtable.common.exception.ErrorCode.ALREADY_EXIST_OWNER;
import static com.prgrms.catchtable.common.exception.ErrorCode.BAD_REQUEST_EMAIL_OR_PASSWORD;
import static com.prgrms.catchtable.common.exception.ErrorCode.INVALID_EMAIL_OR_PASSWORD;

import com.prgrms.catchtable.common.Role;
import com.prgrms.catchtable.common.exception.custom.BadRequestCustomException;
import com.prgrms.catchtable.jwt.provider.JwtTokenProvider;
import com.prgrms.catchtable.jwt.service.RefreshTokenService;
import com.prgrms.catchtable.jwt.token.Token;
import com.prgrms.catchtable.member.domain.Gender;
import com.prgrms.catchtable.owner.domain.Owner;
Expand All @@ -16,6 +18,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
Expand All @@ -24,7 +27,9 @@ public class OwnerService {
private final OwnerRepository ownerRepository;
private final PasswordEncoder passwordEncoder;
private final JwtTokenProvider jwtTokenProvider;
private final RefreshTokenService refreshTokenService;

@Transactional
public JoinOwnerResponse joinOwner(JoinOwnerRequest joinOwnerRequest) {

//이미 존재하는 이메일이라면
Expand All @@ -47,22 +52,29 @@ private void validateExistsOwner(JoinOwnerRequest joinOwnerRequest) {
}
}

@Transactional
public Token loginOwner(LoginOwnerRequest loginRequest) {

//email 확인
Owner loginOwner = ownerRepository.findOwnerByEmail(loginRequest.email())
.orElseThrow(() -> new BadRequestCustomException(BAD_REQUEST_EMAIL_OR_PASSWORD));
.orElseThrow(() -> new BadRequestCustomException(INVALID_EMAIL_OR_PASSWORD));

//password 확인
validatePassword(loginRequest, loginOwner);

return jwtTokenProvider.createToken(loginOwner.getEmail());
return createTotalToken(loginOwner.getEmail());
}

private void validatePassword(LoginOwnerRequest loginRequest, Owner loginOwner) {
if (!passwordEncoder.matches(loginRequest.password(), loginOwner.getPassword())) {
throw new BadRequestCustomException(BAD_REQUEST_EMAIL_OR_PASSWORD);
throw new BadRequestCustomException(INVALID_EMAIL_OR_PASSWORD);
}
}

private Token createTotalToken(String email) {
Token totalToken = jwtTokenProvider.createToken(email, Role.OWNER);
refreshTokenService.saveRefreshToken(totalToken);
return totalToken;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;

import com.prgrms.catchtable.common.Role;
import com.prgrms.catchtable.jwt.config.JwtConfig;
import com.prgrms.catchtable.jwt.service.JwtUserDetailsService;
import com.prgrms.catchtable.jwt.token.Token;
Expand Down Expand Up @@ -34,7 +35,7 @@ void validToken() {
when(config.getClientSecret()).thenReturn(clientKey);
when(config.getExpiryMinute()).thenReturn(1);
when(config.getExpiryMinuteRefresh()).thenReturn(1);
Token token = jwtTokenProvider.createToken(email);
Token token = jwtTokenProvider.createToken(email, Role.MEMBER);

//then
assertThat(jwtTokenProvider.validateToken(token.getAccessToken())).isTrue();
Expand All @@ -48,7 +49,7 @@ void invalidToken() {
when(config.getClientSecret()).thenReturn(clientKey);
when(config.getExpiryMinute()).thenReturn(0);
when(config.getExpiryMinuteRefresh()).thenReturn(0);
Token token = jwtTokenProvider.createToken(email);
Token token = jwtTokenProvider.createToken(email, Role.OWNER);

//then
assertThat(jwtTokenProvider.validateToken(token.getAccessToken())).isFalse();
Expand All @@ -65,9 +66,9 @@ void getAuthenticationTest() {
when(config.getClientSecret()).thenReturn(clientKey);
when(config.getExpiryMinute()).thenReturn(1);
when(config.getExpiryMinuteRefresh()).thenReturn(1);
Token token = jwtTokenProvider.createToken(email);
Token token = jwtTokenProvider.createToken(email, Role.MEMBER);

when(jwtUserDetailsService.loadUserByUsername(email))
when(jwtUserDetailsService.loadUserByUsername(email, Role.MEMBER))
.thenReturn(member);

//then
Expand Down
Loading

0 comments on commit 0e120f4

Please sign in to comment.