Skip to content

Commit

Permalink
fix: admin token (#231)
Browse files Browse the repository at this point in the history
* feat: 회원의 랭킹 redis에 추가 및 삭제, 업데이트 기능 추가

* test: 회원 정보 변경 및 삭제 추가에 따른 랭킹 참여, 제외 테스트 코드 추가

* feat: 랭킹시스템 API 추가 및 랭킹 조회 기능 추가

* feat: 랭킹 조회 테스트 코드 추가 및 랭킹 업데이트 로직 각 업데이트 -> 스케쥴러

* style: checkstyle 에러 fix

* refactor: 응답 객체명 변경 TopRankingInfoResponse -> TopRankingInfo

* fix: 랭킹 업데이트 시간 15분 매초마다 동작하는 방식 -> 15분에 한 번만 실행되도록 변경

* refactor: 랭킹 응답 반환 객체 변수면 s 제거

Co-authored-by: Kim Heebin <blowhuiee@gmail.com>

* refactor: ToprankingResponses 응답 객체 반환명 TopRankingResponse로 변경

* fix: ObjectMapper에러 수정

* fix: objectMapper 삭제 추가

* feat: 어드민 서비스 로그인 기능 추가

* refactor: 어드민 config 업데이트

* fix: test application.yml 수정

* test: stub에서의 타입 오류 해결

* style: 변수면 변경

* feat: 어드민과 일반 유저간 토큰 생성, 검증 분리 및 로그인 분리

* feat: 회원 인증시 뱃지 생성기능 추가

* refactor: config 수정

* refactor: 코딩 스타일 재적용

---------

Co-authored-by: Kim Heebin <blowhuiee@gmail.com>
  • Loading branch information
parksey and kmebin authored Dec 3, 2023
1 parent 12b5f08 commit eaaad58
Show file tree
Hide file tree
Showing 42 changed files with 416 additions and 185 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

import com.moabam.admin.domain.admin.Admin;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class AdminMapper {

public static Admin toAdmin(Long socialId) {
Expand Down
19 changes: 10 additions & 9 deletions src/main/java/com/moabam/admin/application/admin/AdminService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,27 @@

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.moabam.admin.domain.admin.Admin;
import com.moabam.admin.domain.admin.AdminRepository;
import com.moabam.api.application.auth.AuthorizationService;
import com.moabam.api.application.auth.mapper.AuthMapper;
import com.moabam.api.dto.auth.AuthorizationTokenInfoResponse;
import com.moabam.api.dto.auth.LoginResponse;
import com.moabam.global.error.exception.BadRequestException;
import com.moabam.global.error.exception.NotFoundException;
import com.moabam.global.error.model.ErrorMessage;

import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class AdminService {

@Value("${admin}")
private String adminLoginKey;

private final AuthorizationService authorizationService;
private final AdminRepository adminRepository;

public void validate(String state) {
Expand All @@ -33,12 +33,9 @@ public void validate(String state) {
}
}

public LoginResponse signUpOrLogin(HttpServletResponse httpServletResponse,
AuthorizationTokenInfoResponse authorizationTokenInfoResponse) {
LoginResponse loginResponse = login(authorizationTokenInfoResponse);
authorizationService.issueServiceToken(httpServletResponse, loginResponse.publicClaim());

return loginResponse;
@Transactional
public LoginResponse signUpOrLogin(AuthorizationTokenInfoResponse authorizationTokenInfoResponse) {
return login(authorizationTokenInfoResponse);
}

private LoginResponse login(AuthorizationTokenInfoResponse authorizationTokenInfoResponse) {
Expand All @@ -53,4 +50,8 @@ private Admin signUp(Long socialId) {

return adminRepository.save(admin);
}

public Admin findMember(Long id) {
return adminRepository.findById(id).orElseThrow(() -> new NotFoundException(ErrorMessage.MEMBER_NOT_FOUND));
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/moabam/admin/domain/admin/Admin.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class Admin extends BaseTimeEntity {

@Enumerated(EnumType.STRING)
@Column(name = "role", nullable = false)
@ColumnDefault("'USER'")
@ColumnDefault("'ADMIN'")
private Role role;

@Builder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ public LoginResponse authorizationTokenIssue(@RequestBody AuthorizationCodeRespo
HttpServletResponse httpServletResponse) {
adminService.validate(authorizationCodeResponse.state());
AuthorizationTokenResponse tokenResponse = authorizationService.requestAdminToken(authorizationCodeResponse);
AuthorizationTokenInfoResponse authorizationTokenInfoResponse = authorizationService.requestTokenInfo(
tokenResponse);
AuthorizationTokenInfoResponse authorizationTokenInfoResponse =
authorizationService.requestTokenInfo(tokenResponse);
LoginResponse loginResponse = adminService.signUpOrLogin(authorizationTokenInfoResponse);
authorizationService.issueServiceToken(httpServletResponse, loginResponse.publicClaim());

return adminService.signUpOrLogin(httpServletResponse, authorizationTokenInfoResponse);
return loginResponse;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
import org.springframework.util.MultiValueMap;
import org.springframework.web.util.UriComponentsBuilder;

import com.moabam.admin.application.admin.AdminService;
import com.moabam.api.application.auth.mapper.AuthMapper;
import com.moabam.api.application.auth.mapper.AuthorizationMapper;
import com.moabam.api.application.member.MemberService;
import com.moabam.api.domain.auth.repository.TokenRepository;
import com.moabam.api.domain.member.Member;
import com.moabam.api.domain.member.Role;
import com.moabam.api.dto.auth.AuthorizationCodeRequest;
import com.moabam.api.dto.auth.AuthorizationCodeResponse;
import com.moabam.api.dto.auth.AuthorizationTokenInfoResponse;
Expand All @@ -24,8 +26,9 @@
import com.moabam.api.infrastructure.fcm.FcmService;
import com.moabam.global.auth.model.AuthMember;
import com.moabam.global.auth.model.PublicClaim;
import com.moabam.global.common.util.CookieUtils;
import com.moabam.global.common.util.GlobalConstant;
import com.moabam.global.common.util.cookie.CookieUtils;
import com.moabam.global.config.AllowOriginConfig;
import com.moabam.global.config.OAuthConfig;
import com.moabam.global.config.TokenConfig;
import com.moabam.global.error.exception.BadRequestException;
Expand All @@ -47,9 +50,10 @@ public class AuthorizationService {
private final TokenConfig tokenConfig;
private final OAuth2AuthorizationServerRequestService oauth2AuthorizationServerRequestService;
private final MemberService memberService;
private final AdminService adminService;
private final JwtProviderService jwtProviderService;
private final TokenRepository tokenRepository;
private final CookieUtils cookieUtils;
private final AllowOriginConfig allowOriginsConfig;

public void redirectToLoginPage(HttpServletResponse httpServletResponse) {
String authorizationCodeUri = getAuthorizationCodeUri();
Expand Down Expand Up @@ -87,24 +91,25 @@ public LoginResponse signUpOrLogin(HttpServletResponse httpServletResponse,

public void issueServiceToken(HttpServletResponse response, PublicClaim publicClaim) {
String accessToken = jwtProviderService.provideAccessToken(publicClaim);
String refreshToken = jwtProviderService.provideRefreshToken();
String refreshToken = jwtProviderService.provideRefreshToken(publicClaim.role());
TokenSaveValue tokenSaveRequest = AuthMapper.toTokenSaveValue(refreshToken, null);

tokenRepository.saveToken(publicClaim.id(), tokenSaveRequest);
tokenRepository.saveToken(publicClaim.id(), tokenSaveRequest, publicClaim.role());

String domain = getDomain(publicClaim.role());

response.addCookie(CookieUtils.typeCookie("Bearer", tokenConfig.getRefreshExpire(), domain));
response.addCookie(
cookieUtils.typeCookie("Bearer", tokenConfig.getRefreshExpire()));
response.addCookie(
cookieUtils.tokenCookie("access_token", accessToken, tokenConfig.getRefreshExpire()));
CookieUtils.tokenCookie("access_token", accessToken, tokenConfig.getRefreshExpire(), domain));
response.addCookie(
cookieUtils.tokenCookie("refresh_token", refreshToken, tokenConfig.getRefreshExpire()));
CookieUtils.tokenCookie("refresh_token", refreshToken, tokenConfig.getRefreshExpire(), domain));
}

public void validTokenPair(Long id, String oldRefreshToken) {
TokenSaveValue tokenSaveValue = tokenRepository.getTokenSaveValue(id);
public void validTokenPair(Long id, String oldRefreshToken, Role role) {
TokenSaveValue tokenSaveValue = tokenRepository.getTokenSaveValue(id, role);

if (!tokenSaveValue.refreshToken().equals(oldRefreshToken)) {
tokenRepository.delete(id);
tokenRepository.delete(id, role);

throw new UnauthorizedException(ErrorMessage.AUTHENTICATE_FAIL);
}
Expand All @@ -113,7 +118,7 @@ public void validTokenPair(Long id, String oldRefreshToken) {
public void logout(AuthMember authMember, HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) {
removeToken(httpServletRequest, httpServletResponse);
tokenRepository.delete(authMember.id());
tokenRepository.delete(authMember.id(), authMember.role());
fcmService.deleteTokenByMemberId(authMember.id());
}

Expand All @@ -122,12 +127,11 @@ public void removeToken(HttpServletRequest httpServletRequest, HttpServletRespon
return;
}

Arrays.stream(httpServletRequest.getCookies())
.forEach(cookie -> {
if (cookie.getName().contains("token")) {
httpServletResponse.addCookie(cookieUtils.deleteCookie(cookie));
}
});
Arrays.stream(httpServletRequest.getCookies()).forEach(cookie -> {
if (cookie.getName().contains("token")) {
httpServletResponse.addCookie(CookieUtils.deleteCookie(cookie));
}
});
}

@Transactional
Expand All @@ -137,12 +141,18 @@ public void unLinkMember(AuthMember authMember) {
memberService.delete(member);
}

private String getDomain(Role role) {
if (role.equals(Role.ADMIN)) {
return allowOriginsConfig.adminDomain();
}

return allowOriginsConfig.domain();
}

private void unlinkRequest(String socialId) {
try {
oauth2AuthorizationServerRequestService.unlinkMemberRequest(
oAuthConfig.provider().unlink(),
oAuthConfig.client().adminKey(),
unlinkRequestParam(socialId));
oauth2AuthorizationServerRequestService.unlinkMemberRequest(oAuthConfig.provider().unlink(),
oAuthConfig.client().adminKey(), unlinkRequestParam(socialId));
log.info("회원 탈퇴 성공 : [socialId={}]", socialId);
} catch (BadRequestException badRequestException) {
log.warn("회원 탈퇴요청 실패 : 카카오 연결 오류");
Expand Down Expand Up @@ -174,8 +184,7 @@ private String generateQueryParamsWith(AuthorizationCodeRequest authorizationCod
.queryParam("client_id", authorizationCodeRequest.clientId())
.queryParam("redirect_uri", authorizationCodeRequest.redirectUri());

if (authorizationCodeRequest.scope() != null
&& !authorizationCodeRequest.scope().isEmpty()) {
if (authorizationCodeRequest.scope() != null && !authorizationCodeRequest.scope().isEmpty()) {
String scopes = String.join(",", authorizationCodeRequest.scope());
authorizationCodeUri.queryParam("scope", scopes);
}
Expand All @@ -194,8 +203,8 @@ private AuthorizationTokenResponse issueTokenToAuthorizationServer(String code,
oAuthConfig, code, redirectUri);
MultiValueMap<String, String> uriParams = generateTokenRequest(authorizationTokenRequest);
ResponseEntity<AuthorizationTokenResponse> authorizationTokenResponse =
oauth2AuthorizationServerRequestService.requestAuthorizationServer(oAuthConfig.provider().tokenUri(),
uriParams);
oauth2AuthorizationServerRequestService
.requestAuthorizationServer(oAuthConfig.provider().tokenUri(), uriParams);

return authorizationTokenResponse.getBody();
}
Expand All @@ -213,4 +222,14 @@ private MultiValueMap<String, String> generateTokenRequest(AuthorizationTokenReq

return contents;
}

public void validMemberExist(Long id, Role role) {
if (role.equals(Role.ADMIN)) {
adminService.findMember(id);

return;
}

memberService.findMember(id);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.moabam.api.application.auth;

import java.nio.charset.StandardCharsets;
import java.security.Key;

import org.json.JSONObject;
import org.springframework.stereotype.Service;

import com.moabam.api.application.auth.mapper.AuthorizationMapper;
import com.moabam.api.domain.member.Role;
import com.moabam.global.auth.model.PublicClaim;
import com.moabam.global.config.TokenConfig;
import com.moabam.global.error.exception.UnauthorizedException;
Expand All @@ -22,10 +24,12 @@ public class JwtAuthenticationService {

private final TokenConfig tokenConfig;

public boolean isTokenExpire(String token) {
public boolean isTokenExpire(String token, Role role) {
try {
Key key = getSecret(role);

Jwts.parserBuilder()
.setSigningKey(tokenConfig.getKey())
.setSigningKey(key)
.build()
.parseClaimsJws(token);
return false;
Expand All @@ -36,6 +40,14 @@ public boolean isTokenExpire(String token) {
}
}

private Key getSecret(Role role) {
if (role.equals(Role.ADMIN)) {
return tokenConfig.getAdminKey();
}

return tokenConfig.getKey();
}

public PublicClaim parseClaim(String token) {
String claims = token.split("\\.")[1];
byte[] claimsBytes = Decoders.BASE64URL.decode(claims);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.moabam.api.application.auth;

import java.security.Key;
import java.util.Date;

import org.springframework.stereotype.Service;

import com.moabam.api.domain.member.Role;
import com.moabam.global.auth.model.PublicClaim;
import com.moabam.global.config.TokenConfig;

Expand All @@ -22,23 +24,23 @@ public String provideAccessToken(PublicClaim publicClaim) {
return generateIdToken(publicClaim, tokenConfig.getAccessExpire());
}

public String provideRefreshToken() {
return generateCommonInfo(tokenConfig.getRefreshExpire());
public String provideRefreshToken(Role role) {
return generateCommonInfo(tokenConfig.getRefreshExpire(), role);
}

private String generateIdToken(PublicClaim publicClaim, long expireTime) {
return commonInfo(expireTime)
return commonInfo(expireTime, publicClaim.role())
.claim("id", publicClaim.id())
.claim("nickname", publicClaim.nickname())
.claim("role", publicClaim.role())
.compact();
}

private String generateCommonInfo(long expireTime) {
return commonInfo(expireTime).compact();
private String generateCommonInfo(long expireTime, Role role) {
return commonInfo(expireTime, role).compact();
}

private JwtBuilder commonInfo(long expireTime) {
private JwtBuilder commonInfo(long expireTime, Role role) {
Date issueDate = new Date();
Date expireDate = new Date(issueDate.getTime() + expireTime);

Expand All @@ -48,6 +50,14 @@ private JwtBuilder commonInfo(long expireTime) {
.setIssuer(tokenConfig.getIss())
.setIssuedAt(issueDate)
.setExpiration(expireDate)
.signWith(tokenConfig.getKey(), SignatureAlgorithm.HS256);
.signWith(getSecretKey(role), SignatureAlgorithm.HS256);
}

private Key getSecretKey(Role role) {
if (role.equals(Role.ADMIN)) {
return tokenConfig.getAdminKey();
}

return tokenConfig.getKey();
}
}
32 changes: 32 additions & 0 deletions src/main/java/com/moabam/api/application/member/BadgeService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.moabam.api.application.member;

import java.util.Optional;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.moabam.api.domain.member.Badge;
import com.moabam.api.domain.member.BadgeType;
import com.moabam.api.domain.member.repository.BadgeRepository;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class BadgeService {

private final BadgeRepository badgeRepository;

public void createBadge(Long memberId, long certifyCount) {
Optional<BadgeType> badgeType = BadgeType.getBadgeFrom(certifyCount);

if (badgeType.isEmpty()
|| badgeRepository.existsByMemberIdAndType(memberId, badgeType.get())) {
return;
}

Badge badge = MemberMapper.toBadge(memberId, badgeType.get());
badgeRepository.save(badge);
}
}
Loading

0 comments on commit eaaad58

Please sign in to comment.