Skip to content

Commit 3ff7f94

Browse files
committed
feat/OPS-328 : 확장 프로그램 로그인 메소드 추가 및 데이터 캐싱 메소드 추가.
1 parent 194ba3f commit 3ff7f94

File tree

8 files changed

+137
-20
lines changed

8 files changed

+137
-20
lines changed

src/main/java/org/tuna/zoopzoop/backend/domain/auth/controller/ApiV1AuthController.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import org.springframework.http.ResponseEntity;
1111
import org.springframework.security.core.AuthenticationException;
1212
import org.springframework.web.bind.annotation.*;
13+
import org.tuna.zoopzoop.backend.domain.auth.dto.AuthResultData;
14+
import org.tuna.zoopzoop.backend.domain.auth.entity.AuthResult;
1315
import org.tuna.zoopzoop.backend.domain.auth.entity.RefreshToken;
1416
import org.tuna.zoopzoop.backend.domain.auth.service.RefreshTokenService;
1517
import org.tuna.zoopzoop.backend.domain.member.entity.Member;
@@ -23,6 +25,7 @@
2325
public class ApiV1AuthController {
2426
private final JwtUtil jwtUtil;
2527
private final RefreshTokenService refreshTokenService;
28+
private final AuthResult authResult;
2629

2730
/**
2831
* 사용자 로그아웃 API
@@ -118,4 +121,29 @@ public ResponseEntity<RsData<Void>> refreshToken(
118121
.status(HttpStatus.OK)
119122
.body(new RsData<>("200", "액세스 토큰을 재발급 했습니다.", null));
120123
}
124+
125+
@GetMapping("/result")
126+
@Operation(summary = "확장프로그램 백그라운드 풀링 대응 API")
127+
public ResponseEntity<RsData<AuthResultData>> pullingResult(
128+
@RequestParam String state
129+
) {
130+
AuthResultData resultData = authResult.get(state);
131+
if(resultData == null) {
132+
return ResponseEntity
133+
.status(HttpStatus.NOT_FOUND)
134+
.body(new RsData<>(
135+
"404",
136+
"state에 해당하는 토큰이 준비되지 않았거나, 잘못된 state 입니다.",
137+
null
138+
)
139+
);
140+
}
141+
return ResponseEntity
142+
.status(HttpStatus.OK)
143+
.body(new RsData<>(
144+
"200",
145+
"토큰이 정상적으로 발급되었습니다.",
146+
resultData
147+
));
148+
}
121149
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.tuna.zoopzoop.backend.domain.auth.dto;
2+
3+
public class AuthResultData {
4+
private final String accessToken;
5+
private final String sessionId;
6+
7+
public AuthResultData(String accessToken, String sessionId) {
8+
this.accessToken = accessToken;
9+
this.sessionId = sessionId;
10+
}
11+
12+
public String getAccessToken() {
13+
return accessToken;
14+
}
15+
16+
public String getSessionId() {
17+
return sessionId;
18+
}
19+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.tuna.zoopzoop.backend.domain.auth.entity;
2+
3+
import org.springframework.stereotype.Component;
4+
import org.tuna.zoopzoop.backend.domain.auth.dto.AuthResultData;
5+
import java.util.Map;
6+
import java.util.concurrent.ConcurrentHashMap;
7+
8+
@Component
9+
public class AuthResult {
10+
private final Map<String, AuthResultData> results = new ConcurrentHashMap<>();
11+
12+
public void put(String state, String accessToken, String sessionId) {
13+
results.put(state, new AuthResultData(accessToken, sessionId));
14+
}
15+
16+
public AuthResultData get(String state) {
17+
return results.remove(state);
18+
}
19+
20+
public void consume(String state) {
21+
results.remove(state);
22+
}
23+
}

src/main/java/org/tuna/zoopzoop/backend/domain/auth/global/CustomOAuth2AuthorizationRequestResolver.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package org.tuna.zoopzoop.backend.domain.auth.global;
22

3+
import com.fasterxml.jackson.databind.ObjectMapper;
34
import jakarta.servlet.http.HttpServletRequest;
45
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
56
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizationRequestResolver;
67
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver;
78
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
89

10+
import java.util.Base64;
11+
import java.util.HashMap;
12+
import java.util.Map;
13+
914
public class CustomOAuth2AuthorizationRequestResolver implements OAuth2AuthorizationRequestResolver {
1015

1116
private final OAuth2AuthorizationRequestResolver defaultResolver;
@@ -28,13 +33,25 @@ private OAuth2AuthorizationRequest customize(OAuth2AuthorizationRequest req, Htt
2833
if (req == null) return null;
2934

3035
String source = request.getParameter("source"); // 로그인 시작 시 전달된 source
31-
3236
OAuth2AuthorizationRequest.Builder builder = OAuth2AuthorizationRequest.from(req);
3337

3438
if ("extension".equals(source)) {
35-
// state에 source 정보를 안전하게 포함
36-
builder.state("source:extension;" + req.getState());
39+
String state = request.getParameter("state");
40+
Map<String, String> stateData = new HashMap<>();
41+
stateData.put("source", "extension");
42+
stateData.put("customState", state);
43+
stateData.put("originalState", req.getState());
44+
45+
try {
46+
String encodedState = Base64.getUrlEncoder()
47+
.encodeToString(new ObjectMapper().writeValueAsBytes(stateData));
48+
builder.state(encodedState);
49+
} catch (Exception e) {
50+
e.printStackTrace();
51+
return builder.build();
52+
}
3753
}
54+
3855
return builder.build();
3956
}
4057
}

src/main/java/org/tuna/zoopzoop/backend/domain/auth/handler/OAuth2SuccessHandler.java

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.tuna.zoopzoop.backend.domain.auth.handler;
22

3+
import com.fasterxml.jackson.core.type.TypeReference;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
35
import jakarta.servlet.http.HttpServletRequest;
46
import jakarta.servlet.http.HttpServletResponse;
57
import lombok.RequiredArgsConstructor;
@@ -12,6 +14,7 @@
1214
import org.springframework.security.oauth2.core.user.OAuth2User;
1315
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
1416
import org.springframework.stereotype.Component;
17+
import org.tuna.zoopzoop.backend.domain.auth.entity.AuthResult;
1518
import org.tuna.zoopzoop.backend.domain.auth.service.RefreshTokenService;
1619
import org.tuna.zoopzoop.backend.domain.member.entity.Member;
1720
import org.tuna.zoopzoop.backend.domain.member.repository.MemberRepository;
@@ -21,6 +24,8 @@
2124

2225
import java.io.IOException;
2326
import java.net.URLEncoder;
27+
import java.util.Base64;
28+
import java.util.Map;
2429

2530
@Component
2631
@RequiredArgsConstructor
@@ -31,6 +36,7 @@ public class OAuth2SuccessHandler extends SimpleUrlAuthenticationSuccessHandler
3136
private final MemberRepository memberRepository;
3237
private final MemberService memberService;
3338
private final RefreshTokenService refreshTokenService;
39+
private final AuthResult authResult;
3440

3541
@Value("${front.redirect_domain}")
3642
private String redirect_domain;
@@ -68,20 +74,26 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
6874

6975
log.info("[OAuth2SuccessHandler] Member: {}, SessionId: {}", member.getId(), sessionId);
7076

71-
String source = request.getParameter("source");
7277
String state = request.getParameter("state");
73-
log.info("[OAuth2SuccessHandler] Source: {}", source);
74-
log.info("[OAuth2SuccessHandler] State: {}", state);
75-
boolean isExtension = state != null && state.contains("source:extension");
76-
77-
// 확장 프로그램에서 로그인 했을 경우.
78-
if(isExtension){
79-
String redirectUrl = redirect_domain + "/extension/callback"
80-
+ "?success=true"
81-
+ "&accessToken=" + URLEncoder.encode(accessToken, "UTF-8")
82-
+ "&sessionId=" + URLEncoder.encode(sessionId, "UTF-8");
83-
response.sendRedirect(redirectUrl);
84-
return;
78+
if(state != null && state.startsWith("ey")) {
79+
Map<String, String> stateData = new ObjectMapper().readValue(
80+
Base64.getUrlDecoder().decode(state),
81+
new TypeReference<Map<String, String>>() {
82+
}
83+
);
84+
85+
String source = stateData.get("source");
86+
String customState = stateData.get("customState");
87+
88+
log.info("[OAuth2SuccessHandler] Source: {}", source);
89+
log.info("[OAuth2SuccessHandler] CustomState: {}", customState);
90+
91+
// 확장 프로그램에서 로그인 했을 경우.
92+
if ("extension".equals(source)) {
93+
authResult.put(customState, accessToken, sessionId);
94+
response.sendRedirect(redirect_domain + "/extension/success");
95+
return;
96+
}
8597
}
8698

8799
if ("http://localhost:3000".equals(redirect_domain)) {

src/main/java/org/tuna/zoopzoop/backend/domain/member/controller/ApiV1MemberController.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.tuna.zoopzoop.backend.domain.member.dto.req.ReqBodyForEditMemberName;
1212
import org.tuna.zoopzoop.backend.domain.member.dto.res.ResBodyForEditMemberName;
1313
import org.tuna.zoopzoop.backend.domain.member.dto.res.ResBodyForGetMemberInfo;
14+
import org.tuna.zoopzoop.backend.domain.member.dto.res.ResBodyForGetMemberInfoV2;
1415
import org.tuna.zoopzoop.backend.domain.member.entity.Member;
1516
import org.tuna.zoopzoop.backend.domain.member.service.MemberService;
1617
import org.tuna.zoopzoop.backend.global.rsData.RsData;
@@ -40,7 +41,7 @@ public class ApiV1MemberController {
4041
*/
4142
@GetMapping("/me")
4243
@Operation(summary = "사용자 정보 조회")
43-
public ResponseEntity<RsData<ResBodyForGetMemberInfo>> getMemberInfo(
44+
public ResponseEntity<RsData<ResBodyForGetMemberInfoV2>> getMemberInfo(
4445
@AuthenticationPrincipal CustomUserDetails userDetails
4546
) {
4647
Member member = userDetails.getMember();
@@ -50,7 +51,7 @@ public ResponseEntity<RsData<ResBodyForGetMemberInfo>> getMemberInfo(
5051
new RsData<>(
5152
"200",
5253
"사용자 정보를 조회했습니다.",
53-
new ResBodyForGetMemberInfo(member)
54+
new ResBodyForGetMemberInfoV2(member)
5455
)
5556
);
5657
}

src/main/java/org/tuna/zoopzoop/backend/domain/member/dto/res/ResBodyForGetMemberInfo.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@
55
public record ResBodyForGetMemberInfo(
66
Integer id,
77
String name,
8-
// String email,
98
String profileUrl
109
) {
1110
public ResBodyForGetMemberInfo(Member member){
1211
this(
1312
member.getId(),
1413
member.getName(),
15-
// member.getEmail(),
1614
member.getProfileImageUrl()
1715
);
1816
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.tuna.zoopzoop.backend.domain.member.dto.res;
2+
3+
import org.tuna.zoopzoop.backend.domain.member.entity.Member;
4+
5+
public record ResBodyForGetMemberInfoV2(
6+
Integer id,
7+
String name,
8+
String profileUrl,
9+
String provider
10+
) {
11+
public ResBodyForGetMemberInfoV2(Member member){
12+
this(
13+
member.getId(),
14+
member.getName(),
15+
member.getProfileImageUrl(),
16+
member.getProvider().name()
17+
);
18+
}
19+
}

0 commit comments

Comments
 (0)