Skip to content

Commit

Permalink
[BE] feat: 로그아웃 기능 구현 (#440)
Browse files Browse the repository at this point in the history
  • Loading branch information
J-I-H-O authored Aug 16, 2024
1 parent 2657628 commit 7926e9b
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/backend-cd-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,5 @@ jobs:
cd backend/build/libs
echo "File creation time(KR-09:00):"
ls -l --time=ctime friendogly-0.0.1-SNAPSHOT.jar
sudo nohup java -jar friendogly-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev --jwt.secret-key=${{ secrets.JWT_SECRET_KEY }} --jwt.access-expiration-time=${{ secrets.JWT_ACCESS_EXPIRATION_TIME }} --jwt.refresh-expiration-time=${{ secrets.JWT_REFRESH_EXPIRATION_TIME }} &
sudo nohup java -jar friendogly-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev --jwt.secret-key=${{ secrets.JWT_SECRET_KEY }} --jwt.access-expiration-time=${{ secrets.JWT_ACCESS_EXPIRATION_TIME }} --jwt.refresh-expiration-time=${{ secrets.JWT_REFRESH_EXPIRATION_TIME }} --kakao.admin-key=${{ secrets.KAKAO_ADMIN_KEY }} &
echo "start backend server"
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.happy.friendogly.auth.controller;

import com.happy.friendogly.auth.Auth;
import com.happy.friendogly.auth.dto.KakaoLoginRequest;
import com.happy.friendogly.auth.dto.KakaoLoginResponse;
import com.happy.friendogly.auth.dto.KakaoRefreshRequest;
import com.happy.friendogly.auth.dto.TokenResponse;
import com.happy.friendogly.auth.service.AuthService;
import com.happy.friendogly.auth.service.KakaoMemberService;
import com.happy.friendogly.common.ApiResponse;
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;
Expand All @@ -16,6 +18,7 @@
@RequestMapping("/auth")
public class AuthController {

// TODO: KakaoMemberService와 AuthService 통합
private final KakaoMemberService kakaoMemberService;
private final AuthService authService;

Expand All @@ -32,6 +35,12 @@ public ApiResponse<KakaoLoginResponse> login(@RequestBody KakaoLoginRequest requ
return ApiResponse.ofSuccess(kakaoMemberService.login(request));
}

@PostMapping("/kakao/logout")
public ResponseEntity<Void> logout(@Auth Long memberId) {
kakaoMemberService.logout(memberId);
return ResponseEntity.noContent().build();
}

@PostMapping("/kakao/refresh")
public ApiResponse<TokenResponse> refreshToken(@RequestBody KakaoRefreshRequest request) {
return ApiResponse.ofSuccess(authService.refreshToken(request.refreshToken()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@

public interface KakaoMemberRepository extends JpaRepository<KakaoMember, Long> {

Optional<KakaoMember> findByKakaoMemberId(String KakaoMemberId);
Optional<KakaoMember> findByMemberId(Long memberId);

Optional<KakaoMember> findByKakaoMemberId(String kakaoMemberId);

Optional<KakaoMember> findByRefreshToken(String refreshToken);

default KakaoMember getByRefreshToken(String refreshToken) {
return findByRefreshToken(refreshToken)
.orElseThrow(() -> new FriendoglyException("유효하지 않은 리프레시 토큰입니다.", HttpStatus.UNAUTHORIZED));
}

default KakaoMember getByMemberId(Long memberId) {
return findByMemberId(memberId)
.orElseThrow(() -> new FriendoglyException("존재하지 않는 회원입니다.", HttpStatus.UNAUTHORIZED));
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,10 @@ public KakaoLoginResponse login(KakaoLoginRequest request) {
}
return KakaoLoginResponse.ofNotRegistered();
}

public void logout(Long memberId) {
KakaoMember kakaoMember = kakaoMemberRepository.getByMemberId(memberId);
// kakaoOauthClient.logout(kakaoMember.getKakaoMemberId());
kakaoMember.updateRefreshToken(null);
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
package com.happy.friendogly.auth.service;

import com.happy.friendogly.auth.dto.KakaoUserResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClient;

@Component
public class KakaoOauthClient {

private static final String KAKAO_REQUEST_USER_INFO_URI = "https://kapi.kakao.com/v2/user/me";
private static final String KAKAO_REQUEST_LOGOUT_URI = "https://kapi.kakao.com/v1/user/logout";
private static final String BEARER = "Bearer ";
private static final String KAKAO_AK = "KakaoAK ";

private final RestClient restClient;
private final AuthErrorHandler errorHandler;
private final String adminKey;

public KakaoOauthClient(AuthErrorHandler errorHandler) {
public KakaoOauthClient(
AuthErrorHandler errorHandler,
@Value("${kakao.admin-key}") String adminKey
) {
this.restClient = RestClient.create();
this.errorHandler = errorHandler;
this.adminKey = adminKey;
}

// TODO: 타임아웃 설정
Expand All @@ -30,4 +40,19 @@ public KakaoUserResponse getUserInfo(String accessToken) {
.onStatus(errorHandler)
.body(KakaoUserResponse.class);
}

// TODO: 타임아웃 설정
public void logout(String targetKakaoMemberId) {
MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
requestBody.add("target_id_type", "user_id");
requestBody.add("target_id", targetKakaoMemberId);

restClient.post()
.uri(KAKAO_REQUEST_LOGOUT_URI)
.header(HttpHeaders.AUTHORIZATION, KAKAO_AK + adminKey)
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.body(requestBody)
.retrieve()
.onStatus(errorHandler);
}
}
3 changes: 3 additions & 0 deletions backend/src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ jwt:
access-expiration-time: ${JWT_ACCESS_EXPIRATION_TIME}
refresh-expiration-time: ${JWT_REFRESH_EXPIRATION_TIME}

kakao:
admin-key: ${KAKAO_ADMIN_KEY}

management:
endpoint:
metrics:
Expand Down
8 changes: 4 additions & 4 deletions backend/src/main/resources/data.sql
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
INSERT INTO member(name, tag, image_url)
VALUES ('도도', '4e52d416', 'https://avatars.githubusercontent.com/u/79188587?v=4'),
('땡이', 'a582a275', 'https://avatars.githubusercontent.com/u/110461155?v=4'),
('트레', '68fc8014', null),
('트레', '68fc8014', ''),
('위브', '3dde7373', 'https://avatars.githubusercontent.com/u/28584160?v=4'),
('벼리', '525ec19f', null),
('누누', '5f0f8307', null),
('벼리', '525ec19f', ''),
('누누', '5f0f8307', ''),
('채드', '114d8979', 'https://avatars.githubusercontent.com/u/102402485?v=4'),
('에디', 'c065a053', null);
('에디', 'c065a053', '');

INSERT INTO footprint(member_id, latitude, longitude, walk_status, created_at, is_deleted)
VALUES (1, 37.5173316, 127.1011661, 'BEFORE', TIMESTAMPADD(MINUTE, -10, NOW()), FALSE),
Expand Down
3 changes: 3 additions & 0 deletions backend/src/test/resources/application-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ jwt:
secret-key: 행복하세요~행복하세요~행복하세요~행복하세요~행복하세요~행복하세요~행복하세요~행복하세요~
access-expiration-time: 5_184_000_000 # 24시간 (ms)
refresh-expiration-time: 36_288_000_000 # 7일 (ms)

kakao:
admin-key: sdfsdfsdfdsfsdfsdf

0 comments on commit 7926e9b

Please sign in to comment.