Skip to content

Commit

Permalink
feat: 애플 로그인 구현 테스트
Browse files Browse the repository at this point in the history
  • Loading branch information
summermong committed Sep 2, 2024
1 parent 6167447 commit 1aeff0d
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 78 deletions.
68 changes: 50 additions & 18 deletions app/apple/test/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,62 @@ import { useEffect } from 'react';

import { LoginLoading, LoginScreen } from '@/features/login';
import { AuthInfoAtom } from '@/store/auth';
import { LoginResponse } from '@/types/authType';
import { AuthResponse } from '@/types/authType';

const Page = () => {
const router = useRouter();
const setAuth = useSetAtom(AuthInfoAtom);

useEffect(() => {
const url = new URL(window.location.href);
const data = url.searchParams.get('data') as string;
const decodedData = decodeURIComponent(data);
const jsonData = JSON.parse(decodedData) as LoginResponse;

setAuth({
isLogined: true,
nickname: jsonData.data.nickname,
userId: jsonData.data.userId,
});

if (jsonData.data.isSignUpComplete) {
router.push('/');
} else {
router.push('/join/nickname');
}
}, [router]);
const handleAuthCallback = async () => {
const queryParams = new URLSearchParams(window.location.search);
const code = queryParams.get('code');
const idToken = queryParams.get('id_token');
const state = queryParams.get('state');
const email = queryParams.get('email') || '';
const name = queryParams.get('name') || '';

if (code && idToken) {
try {
const response = await fetch('/api/apple/oauth', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
code,
idToken,
state,
email,
name,
}),
});

if (response.status === 200) {
const data = (await response.json()) as AuthResponse;

setAuth({
isLogined: true,
nickname: data.data.data.nickname,
userId: data.data.data.userId,
});

if (data.data.data.isSignUpComplete) {
router.push('/');
} else {
router.push('/join/nickname');
}
}
} catch (error) {
console.error('서버 요청 중 오류 발생:', error);
}
} else {
console.error('인증 데이터가 누락되었습니다.');
}
};

void handleAuthCallback();
}, [router, setAuth]);

return (
<>
Expand Down
74 changes: 14 additions & 60 deletions features/login/components/organisms/login-screen.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
'use client';

import { motion } from 'framer-motion';
import { useSetAtom } from 'jotai';
import Image from 'next/image';
import { useRouter } from 'next/navigation';

import {
AppleLogoIcon,
Expand All @@ -12,10 +10,8 @@ import {
} from '@/components/atoms/icons';
import LoginMainCharacter from '@/public/images/login/login-main-character.png';
import SwimieLetterLogo from '@/public/images/login/swimie-letter-logo.png';
import { AuthInfoAtom } from '@/store/auth';
import { css, cva } from '@/styled-system/css';
import { flex } from '@/styled-system/patterns';
import { AuthResponse } from '@/types/authType';

type LoginScreen = {
isAnimate?: boolean;
Expand All @@ -29,29 +25,10 @@ export const LoginScreen = ({ isAnimate = true }: LoginScreen) => {
window.location.href = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID}&redirect_uri=${process.env.NEXT_PUBLIC_GOOGLE_REDIRECT_URI}&response_type=code&scope=email profile&prompt=consent&access_type=offline`;
};

// TODO: nonce 생성 함수 별도 분리 예정
function generateNonceAndState(length = 16) {
const charset =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let nonce = '';
const charsetLength = charset.length;

for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * charsetLength);
nonce += charset[randomIndex];
}

return nonce;
}

const nonce = generateNonceAndState();

const router = useRouter();

const setAuth = useSetAtom(AuthInfoAtom);

const appleLogin = async () => {
try {
const nonce = generateNonceAndState();

window.AppleID.auth.init({
clientId: `${process.env.NEXT_PUBLIC_APPLE_CLIENT_ID}`,
scope: 'name email',
Expand All @@ -63,45 +40,22 @@ export const LoginScreen = ({ isAnimate = true }: LoginScreen) => {
responseMode: 'form_post',
});

const {
authorization: { code, id_token, state },
user,
} = await window.AppleID.auth.signIn();

const response = await fetch('/api/apple/oauth', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
code,
id_token,
state,
email: user?.email || '',
name: user?.name || '',
}),
});

if (response.status === 200) {
const data = (await response.json()) as AuthResponse;

setAuth({
isLogined: true,
nickname: data.data.data.nickname,
userId: data.data.data.userId,
});

if (data.data.data.isSignUpComplete) {
router.push('/');
} else {
router.push('/join/nickname');
}
}
await window.AppleID.auth.signIn();
} catch (error) {
console.error('Error:', error);
console.error('애플 로그인 중 오류 발생:', error);
}
};

function generateNonceAndState(length = 16) {
const charset =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let nonce = '';
for (let i = 0; i < length; i++) {
nonce += charset.charAt(Math.floor(Math.random() * charset.length));
}
return nonce;
}

return (
<div className={loginPage}>
<motion.div
Expand Down

0 comments on commit 1aeff0d

Please sign in to comment.