Skip to content
Merged
2 changes: 1 addition & 1 deletion umc-master/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>홈마스터</title>
<script src="https://t1.kakaocdn.net/kakao_js_sdk/2.7.4/kakao.min.js" crossorigin="anonymous"></script>
<script src="https://developers.kakao.com/sdk/js/kakao.js"></script>
</head>
<body>
<div id="root"></div>
Expand Down
70 changes: 29 additions & 41 deletions umc-master/src/pages/auth/KakaoCallback.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,42 @@
import React, { useEffect } from 'react';
import axios from 'axios';
import { useNavigate } from 'react-router-dom';
import axiosInstance from '@apis/axios-instance';
import { useTokenStore } from '@store/tokenStore';
import { useAuthStore } from '@store/authStore';

const KakaoCallback: React.FC = () => {

const { setAuth } = useAuthStore();
const { setTokens } = useTokenStore();
const navigate = useNavigate();

useEffect(() => {
const getAccessToken = async () => {
const queryParams = new URLSearchParams(window.location.search);
const code = queryParams.get('code');

if (!code) {
console.error('Authorization code not found');
return;
}

try {
// 카카오에서 Access Token 요청
const response = await axios.post('https://kauth.kakao.com/oauth/token', {
grant_type: 'authorization_code',
client_id: import.meta.env.VITE_KAKAO_API_KEY,
redirect_uri: 'http://localhost:3000/oauth/kakao/callback',
code,
});

const kakaoAccessToken = response.data.access_token;

// 백엔드로 카카오 Access Token 전송
const backendResponse = await axios.post('http://localhost:3000/login/kakao', {
kakaoAccessToken,
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');

if (code) {
console.log('✅ 카카오 로그인 코드 확인:', code);

axiosInstance
.post('/login/kakao', { code })
.then((response) => {
const { accessToken, refreshToken } = response.data.result;
setTokens({ accessToken, refreshToken });
localStorage.setItem('accessToken', accessToken);
localStorage.setItem('refreshToken', refreshToken);
setAuth(true);
navigate('/main');
})
.catch(() => {
// console.error('❌ 카카오 로그인 실패:', error.response?.data || error.message);
// alert(error.response?.data?.message || '카카오 로그인에 실패했습니다.');
navigate('/');
});

const { accessToken, refreshToken } = backendResponse.data.result;

// Access Token 및 Refresh Token 저장 (예: 로컬 스토리지)
localStorage.setItem('accessToken', accessToken);
localStorage.setItem('refreshToken', refreshToken);

// 홈 또는 사용자 대시보드로 이동
navigate('/');
} catch (error) {
console.error('Failed to login with Kakao:', error);
}
};

getAccessToken();
} else {
console.warn('⚠️ 카카오 로그인 코드 없음');
}
}, [navigate]);

return <div>카카오 로그인 중…</div>;
return <></>;
};

export default KakaoCallback;
54 changes: 43 additions & 11 deletions umc-master/src/pages/auth/Login_components/InputForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,57 @@ import styled from 'styled-components';
import Input from '@components/Input/Input';
import useInput from '@hooks/useInput';
import { validateEmailFormat, validatePasswordFormat } from '@utils/validation';
import { useState } from 'react';
import { useState, useEffect } from 'react';
import Button from '@components/Button/Button';
import Kakao_Image from '@assets/kakao_login/kakao_login_large_wide.png';
import { useNavigate } from 'react-router-dom';
import axiosInstance from '@apis/axios-instance';
import { useAuthStore } from '@store/authStore';
import { useTokenStore } from '@store/tokenStore';

const KAKAO_REDIRECT_URI =
import.meta.env.MODE === 'development'
? 'http://localhost:5173/oauth/kakao/callback'
: 'https://www.hmaster.shop/oauth/kakao/callback';

const InputForm: React.FC = () => {
const { setAuth } = useAuthStore();
const { setTokens } = useTokenStore.getState();
const { setTokens } = useTokenStore();
const navigate = useNavigate();

useEffect(() => {
if (!window.Kakao) {
console.warn('⚠️ window.Kakao가 없음, SDK 로드 시작');

const script = document.createElement('script');
script.src = 'https://developers.kakao.com/sdk/js/kakao.js';
script.async = true;
script.onload = () => {
console.log('✅ 카카오 SDK 로드 완료:', window.Kakao);
if (window.Kakao && !window.Kakao.isInitialized()) {
console.error('❌ window.Kakao는 있지만 초기화되지 않음! init() 필요');
window.Kakao.init(import.meta.env.VITE_JAVASCRIPT_KEY);
console.log('✅ 카카오 SDK 강제 초기화 완료');
}
};
document.head.appendChild(script);
} else {
console.log('✅ window.Kakao 이미 로드됨');
if (!window.Kakao.isInitialized()) {
console.error('❌ window.Kakao는 있지만 초기화되지 않음! init() 필요');
window.Kakao.init(import.meta.env.VITE_JAVASCRIPT_KEY);
console.log('✅ 카카오 SDK 강제 초기화 완료');
}
}
}, []);

const handleKakaoLogin = () => {
const KAKAO_API_KEY = import.meta.env.VITE_KAKAO_API_KEY;
const kakaoAuthUrl = `https://kauth.kakao.com/oauth/authorize?client_id=${KAKAO_API_KEY}&redirect_uri=http://localhost:3000/oauth/kakao/callback&response_type=code`;
window.location.href = kakaoAuthUrl;
const clientId = import.meta.env.VITE_JAVASCRIPT_KEY;
const redirectUri = encodeURIComponent(KAKAO_REDIRECT_URI);
const fallbackUrl = `https://kauth.kakao.com/oauth/authorize?client_id=${clientId}&redirect_uri=${redirectUri}&response_type=code`;

console.log('✅ fallback URL로 리디렉션:', fallbackUrl);
window.location.href = fallbackUrl;
};

const handleEmailLogin = async () => {
Expand Down Expand Up @@ -72,13 +107,12 @@ const InputForm: React.FC = () => {
e.preventDefault();
setIsSubmitted(true);

// 이메일 및 비밀번호가 비어있는지 체크하고 오류 메시지 표시
if (!email) {
handleEmailError('이메일을 입력해주세요.');
} else {
const emailError = validateEmailFormat(email);
if (emailError) {
handleEmailError(emailError); // 이메일 오류 처리
handleEmailError(emailError);
}
}

Expand All @@ -87,7 +121,7 @@ const InputForm: React.FC = () => {
} else {
const passwordError = validatePasswordFormat(password);
if (passwordError) {
handlePasswordError(passwordError); // 비밀번호 오류 처리
handlePasswordError(passwordError);
}
}

Expand All @@ -110,8 +144,6 @@ const InputForm: React.FC = () => {
await handleEmailLogin();
};

const navigate = useNavigate(); // 추가

return (
<LoginInputForm onSubmit={formSubmitHandler}>
<LoginInput>
Expand All @@ -132,7 +164,7 @@ const InputForm: React.FC = () => {
<Button variant="primary" type="submit">
로그인하기
</Button>
<Button variant="kakao" onClick={handleKakaoLogin}>
<Button variant="kakao" type="button" onClick={handleKakaoLogin}>
<KakaoImage src={Kakao_Image} alt="Kakao Login" />
</Button>
</Buttons>
Expand Down