Closed byyoungjin closed 3 years ago
https://github.com/aws-amplify/amplify-js/issues/5458 <-- not work
해결: 단순 typo --> sign in 후에는 component 가 사라진다.
https://github.com/aws-amplify/amplify-js/issues/5723
cognito 가 뒤에서 모든걸 handle 하기 때문에 id 를반환하지 않는다고함 https://github.com/aws-amplify/amplify-js/issues/5723#issuecomment-627395742
조금더 step 을 나눠서 아래방법으로 시도해봄 https://docs.amplify.aws/lib/auth/advanced/q/platform/js#google-sign-in-react
조금더 step 을 나눠서 아래방법으로 시도해봄 (user pool 을 이용하지않고, identity pool 을 이용함) https://docs.amplify.aws/lib/auth/advanced/q/platform/js#google-sign-in-react
위 방법으로 진행하면 client 단에서 요청이가서 유저가 cookie를 모두 허용해야만 작동한다. https://stackoverflow.com/questions/63631849/google-sign-in-not-working-in-incognito-mode/64011425#64011425
--> 적합하지 않음.
쿠키를 허용하지 않으면 제대로 작동하지 않음 https://github.com/google/google-api-javascript-client/issues/507
쿠키 허용하면 제대로 동작하는데, aws.configure 자체를 userPool 사용할때와는 다르게 해줘야하는것 같음
요런 에러가 뜬다.
서버 안만들기로 생각하고 있으니까, 그냥 일단은 userPool 을 사용하자.
user data 는 로그인후에 Profile 에서 넣을 수있도록하고,
데이터베이스 관리는 auth 와 연관해서 작업해보자.
auth, user 정도는 global context 로 관리할 필요가 있는것같다. auth 가 되어있다고 하더라도, 내가 관리하는 db 에 user 가 register 되어있을 필요가 있고, register 되어있지 않다면 register 하고, 이미 register 되어있다면 context 에 저장하는 로직. user 정보가 profile 페이지에서만 필요할 수도 있지만, 유저에 따라서 어떤 페이지가 보여지게 할지 customizing 할 수도 있으므로, user 정보는 global 하게 관리하는게 맞는 것 같다.
aws-amplify Hub 이용해서
next.js 에서는 _app.ts 파일에 다음과같이 적용하면 될듯하다.
import React, { useEffect, useContext, createContext, useReducer } from 'react';
import { AppProps } from 'next/app';
import { useRouter } from 'next/router';
import produce from 'immer';
import Head from 'next/head';
import Amplify, { API, Storage, Auth, Hub, withSSRContext } from 'aws-amplify';
import { userByProviderKey } from '@/graphql/queries';
import config from '../aws-exports';
import './globals.scss';
Amplify.configure({
...config,
ssr: true,
});
const INITIAL_AUTH_STATE = {
user: null,
auth: null,
isAuthenticated: false,
isSignIned: false,
};
const authReduceer = produce((draft, action) => {
switch (action.type) {
case 'AUTHENTICATE':
draft.auth = action.payload;
draft.isAuthenticated = true;
break;
case 'USER_SIGN_IN':
draft.user = action.payload;
draft.isSignIned = true;
break;
case 'SIGN_OUT':
return INITIAL_AUTH_STATE;
default:
// throw Error('No matching type');
return;
}
}, INITIAL_AUTH_STATE);
export const AuthContext = createContext({});
function MyApp({ Component, pageProps }: AppProps) {
const router = useRouter();
const [authState, dispatch] = useReducer(authReduceer, INITIAL_AUTH_STATE);
const listenAuthHandler = async ({ payload: { event, data } }) => {
switch (event) {
case 'signIn':
dispatch({ type: 'AUTHENTICATE', payload: data });
break;
case 'signOut':
dispatch({ type: 'SIGN_OUT' });
break;
case 'customOAuthState':
try {
const cognitoUser = await Auth.currentAuthenticatedUser();
await userSignIn(cognitoUser);
} catch (e) {
console.log(`e`, e);
}
break;
}
};
const userSignIn = async (cognitoUser) => {
const providerKey = cognitoUser.username;
const userOfProviderKey = await API.graphql({
query: userByProviderKey,
variables: { providerKey },
});
const dbUser = userOfProviderKey.data.userByProviderKey.items[0] ?? null;
if (dbUser) {
dispatch({ type: 'USER_SIGN_IN', payload: dbUser });
console.log(`dbUser`, dbUser);
} else {
router.push('/user/register');
}
};
useEffect(() => {
Hub.listen('auth', listenAuthHandler);
Auth.currentAuthenticatedUser()
.then((cognitoUser) => {
dispatch({ type: 'AUTHENTICATE', payload: cognitoUser });
return cognitoUser;
})
.then((cognitoUser) => {
userSignIn(cognitoUser);
})
.catch((e) => dispatch({ type: 'SIGN_OUT' }));
return () => {
Hub.remove('auth', listenAuthHandler);
};
}, []);
return (
<>
<AuthContext.Provider value={{ authState, dispatch }}>
<Head>
<title>LOG</title>
<link rel="icon" href="/favicon.ico" />
<link
rel="preload"
href="/fonts/Pacifico-Regular.ttf"
as="font"
crossOrigin=""
/>
</Head>
<Component {...pageProps} />
</AuthContext.Provider>
</>
);
}
export default MyApp;
https://dev.to/dabit3/the-complete-guide-to-next-js-authentication-2aco