REST TEMPLATE
•
Spring Framework 에서 HTTP 요청을 보내는 클래스
◦
GET, POST, PUT, PATCH, DELETE 모두 호출 가능
◦
JSON, XML 등의 데이터로 받아올 수 있음
•
해당 페이지 접속
// 20240919091348
// https://jsonplaceholder.typicode.com/posts/2
// https://jsonplaceholder.typicode.com/posts?userId=2
{
"userId": 1,
"id": 2,
"title": "qui est esse",
"body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
}
JSON
복사
◦
https://jsonplaceholder.typicode.com/posts?userId=2
// 20240919091522
// https://jsonplaceholder.typicode.com/posts?userId=2
[
{
"userId": 2,
"id": 11,
"title": "et ea vero quia laudantium autem",
"body": "delectus reiciendis molestiae occaecati non minima eveniet qui voluptatibus\naccusamus in eum beatae sit\nvel qui neque voluptates ut commodi qui incidunt\nut animi commodi"
},
{
"userId": 2,
"id": 12,
"title": "in quibusdam tempore odit est dolorem",
"body": "itaque id aut magnam\npraesentium quia et ea odit et ea voluptas et\nsapiente quia nihil amet occaecati quia id voluptatem\nincidunt ea est distinctio odio"
},
{
"userId": 2,
"id": 13,
"title": "dolorum ut in voluptas mollitia et saepe quo animi",
"body": "aut dicta possimus sint mollitia voluptas commodi quo doloremque\niste corrupti reiciendis voluptatem eius rerum\nsit cumque quod eligendi laborum minima\nperferendis recusandae assumenda consectetur porro architecto ipsum ipsam"
},
{
"userId": 2,
"id": 14,
"title": "voluptatem eligendi optio",
"body": "fuga et accusamus dolorum perferendis illo voluptas\nnon doloremque neque facere\nad qui dolorum molestiae beatae\nsed aut voluptas totam sit illum"
},
{
"userId": 2,
"id": 15,
"title": "eveniet quod temporibus",
"body": "reprehenderit quos placeat\nvelit minima officia dolores impedit repudiandae molestiae nam\nvoluptas recusandae quis delectus\nofficiis harum fugiat vitae"
},
{
"userId": 2,
"id": 16,
"title": "sint suscipit perspiciatis velit dolorum rerum ipsa laboriosam odio",
"body": "suscipit nam nisi quo aperiam aut\nasperiores eos fugit maiores voluptatibus quia\nvoluptatem quis ullam qui in alias quia est\nconsequatur magni mollitia accusamus ea nisi voluptate dicta"
},
{
"userId": 2,
"id": 17,
"title": "fugit voluptas sed molestias voluptatem provident",
"body": "eos voluptas et aut odit natus earum\naspernatur fuga molestiae ullam\ndeserunt ratione qui eos\nqui nihil ratione nemo velit ut aut id quo"
},
{
"userId": 2,
"id": 18,
"title": "voluptate et itaque vero tempora molestiae",
"body": "eveniet quo quis\nlaborum totam consequatur non dolor\nut et est repudiandae\nest voluptatem vel debitis et magnam"
},
{
"userId": 2,
"id": 19,
"title": "adipisci placeat illum aut reiciendis qui",
"body": "illum quis cupiditate provident sit magnam\nea sed aut omnis\nveniam maiores ullam consequatur atque\nadipisci quo iste expedita sit quos voluptas"
},
{
"userId": 2,
"id": 20,
"title": "doloribus ad provident suscipit at",
"body": "qui consequuntur ducimus possimus quisquam amet similique\nsuscipit porro ipsam amet\neos veritatis officiis exercitationem vel fugit aut necessitatibus totam\nomnis rerum consequatur expedita quidem cumque explicabo"
}
]
JSON
복사
•
Spring 5.0 → WebClient 를 사용할 것을 권장
◦
but rest_template으로 진행
•
방식
◦
GET 방식
▪
getForEntity: Get 요청 후, 응답을 ResponseEntity로 반환
▪
getForObject: Get 요청 후, 응답을 원하는 객체로 반환
◦
POST 방식
▪
postForEntity: Post 요청 후, 응다븡ㄹ ResponseEntity로 반환
▪
postForObject: Post 요청 후, 응답을 원하는 객체로 반환
◦
Put, Patch, Delete…
•
rest template 실습
@GetMapping("/news/{id}")
public ResponseEntity<String> getNewsById(@PathVariable("id") int id) {
// RestTemplate 인스턴스를 하나 생성
RestTemplate rt = new RestTemplate();
// 헤더 인스턴스 생성
HttpHeaders headers = new HttpHeaders();
// header 적용
headers.add("Content-Type", "application/json; charset=UTF-8");
HttpEntity<String> httpEntity = new HttpEntity<>(headers);
// URL 주소 만들기
String url = "https://jsonplaceholder.typicod.com/posts/" + id;
try {
// ResponseEntity<String> result = rt.getForEntity(url, String.class);
ResponseEntity<String> result = rt.exchange(url, HttpMethod.GET, httpEntity, String.class);
return result;
} catch (Exception e) {
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.headers(headers).body("에러!");
}
}
Java
복사
oAuth (Google Login 기준)
•
구글 로그인 React에 구성
// 구글 로그인 핸들러
const handleGoogleLogin = () => {
// 구글 로그인 버튼 클릭 시 이동하는 경로 지정
const params = new URLSearchParams({
scope: "email profile",
response_type: "code", // code 응답
redirect_uri: "http://localhost:3000/oauth/google",
client_id: "530115480345-84amh51vqf0h8iq9h06o9qu3g8e0s9np.apps.googleusercontent.com",
});
const GOOGLE_URL = `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`;
// 경로로 이동
window.location.href = GOOGLE_URL;
}
JavaScript
복사
// App.js 쪽
const GoogleLogin = () => {
const code = new URLSearchParams(window.location.search).get("code");
console.log("서버에 전달해야 하는 코드 값 : ", code)
const login = async () => {
try {
const response = await oauthAPI.googleLogin(code);
if (response.status !== 200) {
throw new Error("로그인 실패");
} else {
setCookie("accessToken", response.data.accessToken, { path: "/"} );
window.location.href = "/";
}
} catch (error) {
console.error(error);
}
}
return (
<div>로그인 처리 중 ~</div>
);
}
JavaScript
복사
•
SpringBoot
◦
구글 로그인 기능 구현
▪
controller
package com.kosta.controller;
import com.kosta.domain.response.LoginResponse;
import com.kosta.service.OAuthService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
@RequestMapping("/api/oauth")
@RequiredArgsConstructor
public class OAuthController {
private final OAuthService oAuthService;
// 구글 로그인 기능 - code 전달
@GetMapping("/google")
public ResponseEntity<?> googleSignIn(@RequestParam("code") final String code, HttpServletResponse res) {
log.info("들어온 코드 값 : {}", code);
String accessToken = oAuthService.googleSignIn(code, res);
// code를 통해 사용자 정보를 받아서
// 사용자 정보를 조회하고, 만약 기존에 있는 사용자라면 (oauth 값을 true 로 변경)
// 만약 기존에 없는 사용자라면 (새로 가입 -> DB 추가)
// 사용자에 대한 정보롤 accessToken과 refreshToken을 만들어서 반환
if (accessToken == null || accessToken.equals("")) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(null);
}
LoginResponse loginResponse = LoginResponse.builder()
.accessToken(accessToken)
.build();
return ResponseEntity.ok(loginResponse);
}
}
Java
복사
•
service
package com.kosta.service.Impl;
import com.fasterxml.jackson.databind.JsonNode;
import com.kosta.entity.User;
import com.kosta.repository.UserRepository;
import com.kosta.service.OAuthService;
import com.kosta.util.TokenUtils;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.server.ResponseStatusException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
@Service
@RequiredArgsConstructor
public class OAuthServiceImpl implements OAuthService {
private final UserRepository userRepository;
private final TokenUtils tokenUtils;
@Override
public String googleSignIn(String code, HttpServletResponse res) {
// 1. code를 통해 google에서 제공하는 accessToken 가져온다.
String providedAccessToken = getAccessToken(code);
// 2. google에서 제공하는 accessToken으로 사용자 정보를 추출한다.
User user = generateOAuthUser(providedAccessToken);
// 3. 사용자 정보를 조회하고
// 만약 기존에 있는 사용자라면 (oAuth 인증 여부에 따라 OAUTH True 로 변경)
// 만약 기존에 없는 사용자라면 (새로 가입 -> DB 추가)
user = userRepository.findByEmail(user.getEmail()).orElse(user);
if (user.isOAuth()) {
user.setOAuth(true);
userRepository.save(user);
}
// 4. 자동 로그인 (사용자에 대한 정보롤 accessToken과 refreshToken을 만들어서 반환)
Map<String, String> tokenMap = tokenUtils.generateToken(user);
// DB에 기록
user.setRefreshToken(tokenMap.get("refreshToken"));
userRepository.save(user);
// HEADER에 추가
tokenUtils.setRefreshTokenCookie(res, tokenMap.get("refreshToken"));
// BODY에 추가
return tokenMap.get("accessToken");
}
// Code를 전달, 사용자 정보 요청
// {"sub":"102830464863109364648",
// "name":"Minsung HA",
// "given_name":"Minsung",
// "family_name":"HA",
// "picture":"https://lh3.googleusercontent.com/a/ACg8ocKsuif1zx11QSgpVnO1jmvcfr5STPrCPoEQ3GxXTkiFcAKzWg=s96-c",
// "email":"codesche@gmail.com","email_verified":true}
private User generateOAuthUser(String accessToken) {
String userInfoURI = "https://www.googleapis.com/oauth2/v3/userinfo";
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + accessToken);
RestTemplate rt = new RestTemplate();
// 구글에 저장된 사용자 정보
ResponseEntity<JsonNode> responseEntity = rt.exchange(userInfoURI,
HttpMethod.GET, new HttpEntity<>(headers), JsonNode.class);
// response 상태에 따라 구분
if (!responseEntity.getStatusCode().is2xxSuccessful() || responseEntity.getBody() == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "사용자 정보를 가져올 수 없음");
}
JsonNode jsonNode = responseEntity.getBody();
String email = null;
String name = null;
User user = null;
try {
if (jsonNode.has("email") && jsonNode.has("name")) {
email = jsonNode.get("email").asText();
name = jsonNode.get("name").asText();
user = User.builder()
.email(email)
.name(name)
.build();
}
} catch (RuntimeException e) {
throw new RuntimeException("해당 사용자를 찾을 수 없습니다.");
}
return user;
}
private String getAccessToken(String code) {
// 1. code를 통해 google에서 제공하는 accessToken 가져온다.
String decodedCode = URLDecoder.decode(code, StandardCharsets.UTF_8);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
String clientId = "530115480345-84amh51vqf0h8iq9h06o9qu3g8e0s9np.apps.googleusercontent.com";
String clientSecret = "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";
String redirectURI = "http://localhost:3000/oauth/google";
headers.setBasicAuth(clientId, clientSecret);
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("client_id", clientId);
params.add("client_secret", clientSecret);
params.add("code", decodedCode);
params.add("grant_type", "authorization_code");
params.add("redirect_uri", redirectURI);
// accessToken 받아오기
String tokenURI = "https://oauth2.googleapis.com/token";
RestTemplate rt = new RestTemplate();
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);
ResponseEntity<Map> responseEntity = rt.postForEntity(tokenURI, requestEntity, Map.class);
// response 상태에 따라 구분
if (!responseEntity.getStatusCode().is2xxSuccessful() || responseEntity.getBody() == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "사용자 정보를 가져올 수 없음");
}
return (String) responseEntity.getBody().get("access_token");
}
}
Java
복사
•
security
http.authorizeHttpRequests(auth ->
// 특정 URL 경로에 대해서는 인증 없이 접근 가능
auth.requestMatchers(
new AntPathRequestMatcher("/api/oauth/**"), // 추가 // oAuth 처리 (20240919)
new AntPathRequestMatcher("/api/auth/signup"), // 회원가입
new AntPathRequestMatcher("/api/auth/duplicate"), // 이메일 중복체크
new AntPathRequestMatcher("/img/**"), // 이미지
new AntPathRequestMatcher("/api/auth/refresh-token"), // 토큰 재발급
new AntPathRequestMatcher("/api/post/**", "GET")
).permitAll()
// AuthController 중 나머지들은 "ADMIN"만 가능
.requestMatchers(
new AntPathRequestMatcher("/api/auth/") // "ADMIN"만 가능
).hasRole("ADMIN")
// 그 밖의 다른 요청들은 인증을 통과한(로그인한) 사용자라면 모두 접근할 수 있도록 한다.
.anyRequest().authenticated()
);
Java
복사
oAuth (객체지향에 맞게 코드 리팩토링)
•
application.yml
oauth2:
clients:
google:
client-id: 530115480345-84amh51vqf0h8iq9h06o9qu3g8e0s9np.apps.googleusercontent.com
client-secret: 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
redirect-uri: http://localhost:3000/oauth/google
token-uri: https://oauth2.googleapis.com/token
user-info-request-uri: https://www.googleapis.com/oauth2/v3/userinfo
kakao:
client-id:
client-secret:
redirect-uri:
token-uri:
user-info-request-uri:
YAML
복사
•
util
package com.kosta.util;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Map;
@Data
@Component
@ConfigurationProperties(prefix = "oauth2")
public class OAuth2Properties {
private Map<String, Client> clients;
@Data
public static class Client {
private String clientId;
private String clientSecret;
private String redirectUri;
private String tokenUri;
private String userInfoRequestUri;
}
}
Java
복사
•
service
private User generateOAuthUser(String accessToken, String provider) {
// 설정 가져오기
OAuth2Properties.Client client = oAuth2Properties.getClients().get(provider);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + accessToken);
RestTemplate rt = new RestTemplate();
// 구글에 저장된 사용자 정보
ResponseEntity<JsonNode> responseEntity = rt.exchange(client.getUserInfoRequestUri(),
HttpMethod.GET, new HttpEntity<>(headers), JsonNode.class);
// response 상태에 따라 구분
if (!responseEntity.getStatusCode().is2xxSuccessful() || responseEntity.getBody() == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "사용자 정보를 가져올 수 없음");
}
JsonNode jsonNode = responseEntity.getBody();
System.out.println(jsonNode);
String email = null;
String name = null;
User user = null;
try {
if (jsonNode.has("email") && jsonNode.has("name")) {
email = jsonNode.get("email").asText();
name = jsonNode.get("name").asText();
user = User.builder()
.email(email)
.name(name)
.build();
}
} catch (RuntimeException e) {
throw new RuntimeException("해당 사용자를 찾을 수 없습니다.");
}
return user;
}
private String getAccessToken(String code, String provider) {
// 설정 가져오기
OAuth2Properties.Client client = oAuth2Properties.getClients().get(provider);
// 1. code를 통해 google에서 제공하는 accessToken 가져온다.
String decodedCode = URLDecoder.decode(code, StandardCharsets.UTF_8);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.setBasicAuth(client.getClientId(), client.getClientSecret());
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("client_id", client.getClientId());
params.add("client_secret", client.getClientSecret());
params.add("code", decodedCode);
params.add("grant_type", "authorization_code");
params.add("redirect_uri", client.getRedirectUri());
// accessToken 받아오기
RestTemplate rt = new RestTemplate();
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);
ResponseEntity<Map> responseEntity = rt.postForEntity(client.getTokenUri(), requestEntity, Map.class);
// response 상태에 따라 구분
if (!responseEntity.getStatusCode().is2xxSuccessful() || responseEntity.getBody() == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "사용자 정보를 가져올 수 없음");
}
return (String) responseEntity.getBody().get("access_token");
}
Java
복사
카카오 소셜 로그인 구현 (객체지향에 맞게 수정, react도 유사하게 수정)
•
카카오 소셜 로그인 참고 링크
https://ddonghyeo.tistory.com/16
•
spring
package com.kosta.service.Impl;
import com.fasterxml.jackson.databind.JsonNode;
import com.kosta.entity.User;
import com.kosta.repository.UserRepository;
import com.kosta.service.OAuthService;
import com.kosta.util.OAuth2Properties;
import com.kosta.util.TokenUtils;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.server.ResponseStatusException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
@Service
@RequiredArgsConstructor
public class OAuthServiceImpl implements OAuthService {
private final OAuth2Properties oAuth2Properties;
private final UserRepository userRepository;
private final TokenUtils tokenUtils;
@Override
public String oAuthSignIn(String code, String provider, HttpServletResponse res) {
// 1. code를 통해 provider에서 제공하는 accessToken 가져온다.
String providedAccessToken = getAccessToken(code, provider);
// 2. provider에서 제공하는 accessToken으로 사용자 정보를 추출한다.
User user = generateOAuthUser(providedAccessToken, provider);
// 3. 사용자 정보를 조회하고
// 만약 기존에 있는 사용자라면 (oAuth 인증 여부에 따라 OAUTH True 로 변경)
// 만약 기존에 없는 사용자라면 (새로 가입 -> DB 추가)
user = userRepository.findByEmail(user.getEmail()).orElse(user);
if (user.isOAuth()) {
user.setOAuth(true);
userRepository.save(user);
}
// 4. 자동 로그인 (사용자에 대한 정보롤 accessToken과 refreshToken을 만들어서 반환)
Map<String, String> tokenMap = tokenUtils.generateToken(user);
// DB에 기록하기
user.setRefreshToken(tokenMap.get("refreshToken"));
userRepository.save(user);
// HEADER에 추가
tokenUtils.setRefreshTokenCookie(res, tokenMap.get("refreshToken"));
// BODY에 추가
return tokenMap.get("accessToken");
}
// Code를 전달, 사용자 정보 요청
// {"sub":"102830464863109364648",
// "name":"Minsung HA",
// "given_name":"Minsung",
// "family_name":"HA",
// "picture":"https://lh3.googleusercontent.com/a/ACg8ocKsuif1zx11QSgpVnO1jmvcfr5STPrCPoEQ3GxXTkiFcAKzWg=s96-c",
// "email":"codesche@gmail.com","email_verified":true}
private User generateOAuthUser(String accessToken, String provider) {
// 설정 가져오기
OAuth2Properties.Client client = oAuth2Properties.getClients().get(provider);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + accessToken);
RestTemplate rt = new RestTemplate();
// 구글에 저장된 사용자 정보
ResponseEntity<JsonNode> responseEntity = rt.exchange(client.getUserInfoRequestUri(),
HttpMethod.GET, new HttpEntity<>(headers), JsonNode.class);
// response 상태에 따라 구분
if (!responseEntity.getStatusCode().is2xxSuccessful() || responseEntity.getBody() == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "사용자 정보를 가져올 수 없음");
}
JsonNode jsonNode = responseEntity.getBody();
System.out.println(jsonNode);
String email = null;
String name = null;
User user = null;
try {
if (jsonNode.has("email") && jsonNode.has("name")) {
email = jsonNode.get("email").asText();
name = jsonNode.get("name").asText();
} else if (jsonNode.has("id") && jsonNode.has("properties")) {
email = jsonNode.get("id").asText() + "@kakao.com";
name = jsonNode.get("properties").get("nickname").asText();
}
user = User.builder()
.email(email)
.name(name)
.build();
} catch (RuntimeException e) {
throw new RuntimeException("해당 사용자를 찾을 수 없습니다.");
}
return user;
}
private String getAccessToken(String code, String provider) {
// 설정 가져오기
OAuth2Properties.Client client = oAuth2Properties.getClients().get(provider);
// 1. code를 통해 google에서 제공하는 accessToken 가져온다.
String decodedCode = URLDecoder.decode(code, StandardCharsets.UTF_8);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.setBasicAuth(client.getClientId(), client.getClientSecret());
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("client_id", client.getClientId());
params.add("client_secret", client.getClientSecret());
params.add("code", decodedCode);
params.add("grant_type", "authorization_code");
params.add("redirect_uri", client.getRedirectUri());
// accessToken 받아오기
RestTemplate rt = new RestTemplate();
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);
ResponseEntity<Map> responseEntity = rt.postForEntity(client.getTokenUri(), requestEntity, Map.class);
// response 상태에 따라 구분
if (!responseEntity.getStatusCode().is2xxSuccessful() || responseEntity.getBody() == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "사용자 정보를 가져올 수 없음");
}
return (String) responseEntity.getBody().get("access_token");
}
}
Java
복사
•
react
// Login.jsx를 수정
// 구글 로그인 핸들러
const handleGoogleLogin = () => {
// 구글 로그인 버튼 클릭 시 이동하는 경로 지정
const params = new URLSearchParams({
scope: "email profile",
response_type: "code", // code 응답
redirect_uri: process.env.REACT_APP_GOOGLE_REDIRECT_URI,
client_id: process.env.REACT_APP_GOOGLE_ID,
});
const GOOGLE_URL = `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`;
// 지정한 경로로 이동
window.location.href = GOOGLE_URL;
}
// 카카오 로그인 핸들러
const handleKakaoLogin = () => {
// 구글 로그인 버튼 클릭 시 이동하는 경로 지정
const params = new URLSearchParams({
response_type: "code", // code 응답
redirect_uri: process.env.REACT_APP_KAKAO_REDIRECT_URI,
client_id: process.env.REACT_APP_KAKAO_ID,
});
const KAKAO_URL = `https://kauth.kakao.com/oauth/authorize?${params.toString()}`;
// 지정한 경로로 이동
window.location.href = KAKAO_URL;
}
JavaScript
복사
// OAuthLogin.jsx
import { useEffect } from "react";
import { useParams } from "react-router-dom";
import { oauthAPI } from "../../api/services/oauth";
import { setCookie } from "../../utils/cookieUtil";
// google or kakao 소셜로그인 기능 구분하여 적용될 수 있도록 수정
const OAuthLogin = () => {
const { provider } = useParams();
const code = new URLSearchParams(window.location.search).get("code");
console.log("서버에 전달해야 하는 코드 값 : ", code);
const oAuthAPI = {
"kakao": (code) => oauthAPI.kakaoLogin(code),
"google": (code) => oauthAPI.googleLogin(code)
}
const login = async () => {
try {
console.log(provider);
const response = await oAuthAPI[provider](code);
if (response.status !== 200) {
throw new Error("로그인 실패");
} else {
setCookie("accessToken", response.data.accessToken, { path: "/" });
window.location.href = "/";
}
} catch (error) {
console.error(error);
}
}
useEffect(() => {
login();
}, [code]);
return (
<div>로그인 처리 중 ~</div>
);
}
export default OAuthLogin;
JavaScript
복사
// App.js
// 라우팅 수정
... 중략 ...
<Route path='/oauth/:provider' element={<OAuthLogin />} />
JavaScript
복사


