React에서 AWS Cognito를 사용하는 방법은 두 가지이다.
첫 번째는 Amplify를 활용해서 backend를 구축하는 것이고, 두 번째는 aws-cognito-identity 라이브러리를 활용하는 것이다.
예전에는 Amplify 사용했는데 이번에는 aws-cognito-identity 라이브러리 활용했다.
아래는 AWS Cognito에 user pool이 생성되어 있다는 전제 하에 진행한다.
npm i amazon-cognito-identity-js
아래는 user pool 정보를 설정한 config 파일의 일부이다.
env 파일에 값을 넣어두고, 불러와서 사용했다.
export const COGNITO_API = {
userPoolId: process.env.REACT_APP_AWS_COGNITO_USER_POOL_ID,
clientId: process.env.REACT_APP_AWS_COGNITO_CLIENT_ID,
};
아래는 회원가입, 로그인, 로그아웃을 구현한 코드. 더 다양한 함수는 링크에 가면 확인할 수 있다.
import { useCallback } from 'react';
import {
CognitoUser,
CognitoUserPool,
CognitoUserAttribute,
AuthenticationDetails,
} from 'amazon-cognito-identity-js';
import { COGNITO_API } from '../config';
const userPool = new CognitoUserPool({
UserPoolId: COGNITO_API.userPoolId || '',
ClientId: COGNITO_API.clientId || '',
});
export function AuthProvider({ children }) {
// ... 중간 생략
// LOGIN
const login = useCallback(
(email, password) =>
new Promise((resolve, reject) => {
const userData = new CognitoUser({
Username: email,
Pool: userPool,
});
const authDetails = new AuthenticationDetails({
Username: email,
Password: password,
});
userData.authenticateUser(authDetails, {
onSuccess: (result) => {
getSession();
resolve(result);
},
onFailure: (error) => {
reject(error);
},
});
}),
[getSession]
);
// REGISTER
const register = useCallback(
(email, password, firstName, lastName, country) =>
new Promise((resolve, reject) => {
const newAttributes = [
new CognitoUserAttribute({
Name: 'email',
Value: email,
}),
new CognitoUserAttribute({
Name: 'name',
Value: `${firstName} ${lastName}`,
}),
new CognitoUserAttribute({
Name: 'zoneinfo',
Value: country,
}),
];
userPool.signUp(email, password, newAttributes, [], async (error, result) => {
if (error) {
reject(error);
console.error(error);
return;
}
resolve(result.userSub);
});
}),
[]
);
// Verify code
const confirmcode = useCallback(
(username, code) =>
new Promise((resolve, reject) => {
const userData = {
Username: username,
Pool: userPool,
};
const cognitoUser = new CognitoUser(userData);
cognitoUser.confirmRegistration(code, true, async (error, result) => {
if (error) {
reject(error);
console.error(error);
return;
}
resolve(undefined);
});
}),
[]
);
// Resend verification code
const resendCode = useCallback(
(username) =>
new Promise((resolve, reject) => {
const userData = {
Username: username,
Pool: userPool,
};
const cognitoUser = new CognitoUser(userData);
cognitoUser.resendConfirmationCode(async (error, result) => {
if (error) {
reject(error);
console.error(error);
return;
}
resolve(undefined);
});
}),
[]
);
// LOGOUT
const logout = useCallback(() => {
const cognitoUser = userPool.getCurrentUser();
if (cognitoUser) {
cognitoUser.signOut();
dispatch({
type: 'LOGOUT',
});
}
}, []);
}
const onSubmit = async (data) => {
try {
await login(data.email, data.password);
} catch (error) {
console.error(error);
reset();
setError('afterSubmit', {
...error,
message: error.message || error,
});
}
};