본문 바로가기
프로그래밍/프로젝트

[Backend] 인증/보안 auth-basic-cookie

by monicada 2022. 7. 15.
728x90

과제: 로그인과 로그아웃이 가능하고, 필요에 따라 쿠키에 인증 정보를 넣어 로그인 상태를 유지하는 앱 개발 

 

1. 서버 설치가 어려울 경우 아래의 코드를 통해 설치 

npm install --force

 

2. index.js

const corsOptions = {
  origin: "http://localhost:3000",
  credentials: true,
  methods: ['GET', 'POST', 'OPTION']
};

 

3. Login.js

import React, { useState } from 'react';
import axios from 'axios';

export default function Login({setIsLogin, setUserInfo}) {
  const [loginInfo, setLoginInfo] = useState({
    userId: '',
    password: '',
  });
  const [checkedKeepLogin, setCheckedKeepLogin] = useState(false);
  const [errorMessage, setErrorMessage] = useState('');
  const handleInputValue = (key) => (e) => {
    setLoginInfo({ ...loginInfo, [key]: e.target.value });
  };
  const loginRequestHandler = () => {
    
    // TODO: Login 컴포넌트가 가지고 있는 state를 이용해 로그인을 구현합니다.
    // 로그인에 필요한 유저정보가 충분히 제공되지 않았다면 에러메시지가 나타나도록 구현하세요.
    if (!loginInfo.userId || !loginInfo.password) {
      setErrorMessage('아이디와 비밀번호를 입력하세요')
      return;
    } else {
      setErrorMessage("")
    }
    return axios
      .post("https://localhost:4000/login", {loginInfo, checkedKeepLogin})
      .then((res) => {
        // 로그인에 성공했다면 응답으로 받은 데이터가 Mypage에 렌더링되도록 State를 변경하세요.
        console.log(res.data)
        setUserInfo(res.data)
        setIsLogin(true)
        
      })
      .catch((err) => {
        console.log(err.response.data)
        setErrorMessage("로그인에 실패했습니다.")
      });
    
  };

  return (
    <div className='container'>
      <div className='left-box'>
        <span>
          Education
          <p>for the</p>
          Real World
        </span>
      </div>
      <div className='right-box'>
        <h1>AUTH STATES</h1>
        <form onSubmit={(e) => e.preventDefault()}>
          <div className='input-field'>
            <span>ID</span>
            <input type='text' data-testid='id-input' onChange={handleInputValue('userId')} />
            <span>Password</span>
            <input
              type='password'
              data-testid='password-input'
              onChange={handleInputValue('password')}
            />
            <label className='checkbox-container'>
              <input type='checkbox' onChange={() => setCheckedKeepLogin(!checkedKeepLogin)} />
              {' 로그인 상태 유지하기'}
            </label>
          </div>
          <button type='submit' onClick={loginRequestHandler}>
            LOGIN
          </button>
          {errorMessage ? (
            <div id='alert-message' data-testid='alert-message'>
              {errorMessage}
            </div>
          ) : (
            ''
          )}
        </form>
      </div>
    </div>
  );
}

 

4. Mypage.js

import axios from 'axios';
import React from 'react';

export default function Mypage({ userInfo, setIsLogin, setUserInfo }) {
  const logoutHandler = () => {
    
    // TODO: Logout 버튼을 눌렀을 시 Login 페이지로 돌아갈 수 있도록 구현하세요. 
    return axios
      .post("https://localhost:4000/logout")
      .then((res) => {
        setIsLogin(false)
        setUserInfo(null)
      })
      .catch((err) => {
        console.log(err.response.data) 
      });
    
  };

  return (
    <div className='container'>
      <div className='left-box'>
        <span>
          {`${userInfo.name}(${userInfo.userId})`}님,
          <p>반갑습니다!</p>
        </span>
      </div>
      <div className='right-box'>
        <h1>AUTH STATES</h1>
        <div className='input-field'>
          <h3>내 정보</h3>
          <div className='userinfo-field'>
            <div>{`💻 ${userInfo.position}`}</div>
            <div>{`📩 ${userInfo.email}`}</div>
            <div>{`📍 ${userInfo.location}`}</div>
            <article>
              <h3>Bio</h3>
              <span>{userInfo.bio}</span>
            </article>
          </div>
          <button className='logout-btn' onClick={logoutHandler}>
            LOGOUT
          </button>
        </div>
      </div>
    </div>
  );
}

 

5. App.js

import './App.css';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Login from './pages/Login';
import Mypage from './pages/Mypage';
import React, { useEffect, useState } from 'react';
import axios from 'axios';

// 모든 요청에 withCredentials가 true로 설정됩니다.
axios.defaults.withCredentials = true;

function App() {
  const [isLogin, setIsLogin] = useState(false);
  const [userInfo, setUserInfo] = useState(null);

  const authHandler = () => {
    
    // TODO: 초기 화면 렌더링시, 서버에 유저 정보를 요청하여 Login 또는 Mypage가 렌더링되도록 구현합니다.
    return axios
      .get("https://localhost:4000/userinfo")
      .then((res) => {
        setIsLogin(true)
        setUserInfo(res.data)
      })
      .catch((err) => {
        console.log(err.response.data)
      });
    
  };

  useEffect(() => {
    // 컴포넌트 생성 시 아래 함수가 실행됩니다.
    authHandler();
  }, []);

  return (
    <BrowserRouter>
      <div className='main'>
        <Routes>
          <Route
            path='/'
            element={
              isLogin ? (
                <Mypage
                  setIsLogin={setIsLogin}
                  isLogin={isLogin}
                  setUserInfo={setUserInfo}
                  userInfo={userInfo}
                />
              ) : (
                <Login
                  setIsLogin={setIsLogin}
                  setUserInfo={setUserInfo}
                />
              )
            }
          />
        </Routes>
      </div>
    </BrowserRouter>
  );
}

export default App;

'프로그래밍 > 프로젝트' 카테고리의 다른 글

번들링과 웹팩(web-pack)  (0) 2022.07.25
구글 클론 코딩  (0) 2022.07.24
StatesAirline Client part1  (0) 2022.06.14
React Twittler SPA  (0) 2022.06.03
Beesbeesbees 과제(코드스테이츠)  (0) 2022.05.26

댓글