본문 바로가기

리액트

[인스타그램 클론코딩] 웹 로그인 구현

Amplify 초기화 포스트에서는 귀찮았지만 한 번 셋팅하고 정말 편해집니다.

Auth 컴포넌트는 action 상태에 따라 로그인(logIn), 회원가입(signUp), 인증코드확인(confirm) 화면을 표시하는 컴포넌트입니다. 이번에는 action 상태가 로그인일 때 어떻게 작동하는지 알아보겠습니다.

참고로 Auth 컴포넌트를 데이터 처리를 담당하는 Container와 랜더링을 담당하는 Presenter로 분리했습니다.

AuthContainer.js

Auth 컴포넌트의 데이터 처리를 담당합니다.

보기 편하게 오류 처리 코드와 로그인과 관련 없는 코드는 제외했습니다. 전체 코드는 제 github에서 확인할 수 있습니다.

Amplify 초기화 포스트에서 언급했다시피 코드 두 줄이면 로그인이 끝납니다.

아래 Log in 버튼을 클릭하면 아래 onSubmit 핸들러가 실행됩니다.

Auth.signIn 메소드로 Congnito에서 토큰을 받아오고, 오류가 없으면, [인스타그램 클론코딩] AuthContext 포스트에 설명한 setIsLoggedIn 함수를 사용해서 AuthContext 컴포넌트부터 다시 랜더링시킵니다.

참조: [인스타그램 클론코딩] 웹 로그인 구조

 

추가적으로 Auth 객체는 Cognito에서 받아온 토큰을 자동으로 Local Storage에 저장하기 때문에 앱 시작시 Auth.currentAuthenticatedUser 메소드를 사용하여 Local Storage에 저장된 토큰을 가져올 수 있습니다.

import React, {useState} from "react";
import useInput from "../../Hooks/useInput";
import AuthPresenter from "./AuthPresenter";
import {toast} from "react-toastify";

import { Auth } from 'aws-amplify';
import { useSetIsLoggedIn } from "../../Contexts/AuthContext";

export default() => {
    const setIsLoggedIn = useSetIsLoggedIn();
    const [action, setAction] = useState("logIn");

    const [loading, setLoading] = useState(false);

    const email = useInput("");  // 회원가입할 때만 사용됨
    const password = useInput("");
    const userName = useInput("");
    const firstName = useInput(""); // 회원가입할 때만 사용됨
    const lastName = useInput(""); // 회원가입할 때만 사용됨
    
    const secret = useInput("");

    const onSubmit = async(e) => {
        e.preventDefault();
        if(loading === false) {
            setLoading(true);
            if (action === "logIn") {
                const user = await Auth.signIn(userName.value, password.value);
                console.log(user); 
                setIsLoggedIn(true);
            } else if (action === "signUp") {
                ...
            } else if (action === "confirm") {
                ...
            }
            setLoading(false);
        }
    };

    return (
        <AuthPresenter
            action={action}
            setAction={setAction}
            email={email}
            password={password}
            userName={userName}
            firstName={firstName}
            lastName={lastName}
            secret={secret}
            onSubmit={onSubmit}
            loading={loading}/>
     );
};

Auth.signIn 메소드에서 반환된 user를 출력해 볼까요?

Amplify의 Auth 객체가 Cognito로 부터 다양한 정보를 받아오네요.

여기서 우리에게 필요한건 화살표로 표시한 idToken입니다. 이 토큰은 위에 있는 attributes(이름, 이메일 등 회원가입 정보)를 암호화한 문자열입니다. 나중에 백엔드에서 사용자가 가입된 Cognito User Pool에 접속해서 복호화를 할 것입니다.

AuthPresenter.js

Auth 컴포넌트의 랜더링을 담당합니다.

AuthContainer에서 넘어온 정보와 조건에 따라 랜더링을 수행합니다.

import React from "react";
import styled from "styled-components";
import Input from "../../Components/Input";
import Button from "../../Components/Button";
import Helmet from "rl-react-helmet";
import LoaderDots from "../../Components/LoaderDots";
import { Auth } from 'aws-amplify';
 
export default({
    action,
    setAction,
    email,
    password,
    userName,
    firstName,
    lastName,
    secret,
    onSubmit,
    loading
}) => {
    return (
        <Wrapper>
            {loading && <LoaderDots/>}
            <Form>
                {action === "logIn" && (
                    <>
                      <form onSubmit={onSubmit}>
                        <Input placeholder={"User Name"} {...userName}/>
                        <Input placeholder={"Password"} {...password} type={"password"}/>
                        <Button text={"Log in"} />
                      </form>
                    </>
                )}
                {action === "signUp" && (
                    ...
                )}
                {action === "confirm" && (
                    ...
                )}
            </Form>
        </Wrapper>
    );
};
 

action == "logIn"일 때 랜더링 화면

로그인 화면