버글버글

[React] Cookie에 정보저장하기 본문

React/react 공부기록

[React] Cookie에 정보저장하기

Bugle 2023. 4. 13. 16:16
반응형

Cookie란?

 

 - 클라이언트(웹 브라우저)에 저장되는 작은 데이터 조각이다.

 - 서버 >  웹 브라우저로 데이터를 보내면, 웹 브라우저는 해당 데이터를 로컬에 저장한다.

 - 그리고 다음에 같은 서버로부터 요청이 있을 때마다, 브라우저는 이전에 저장된 데이터를 서버로 보내주어 서버는 해당 정보를 활용하여 사용자에 맞는 웹페이지를 제공하게 된다.

- 보안 문제로 브라우저에서는 쿠키에 접근하는 것이 제한되어 있으며, 쿠키에 저장된 데이터도 중요한 정보는 암호화되어 저장되어야 한다.

- 웹 개발에서 쿠키는 사용자가 로그인을 했는지 여부, 사용자 설정 등을 저장하기 위해 사용된다.

 

 

Cookie 어디에 저장되었는지 확인하기

 

 

1. [F12]로 개발자 도구를 연다.

2. [Application]을 클릭한다.

 

3. [Cookies]를 클릭한다.

값이 들어가기 전
값이 들어간 후

 

 

 

적용하기

 

1. 터미널에 아래 코드 입력해서 설치한다.

npm i react-cookie

2. import 해준다.

import { useCookies } from 'react-cookie';

3. useState Hook 작성

  const [userId, setUserId] = useState('');
  const [userPw, setUserPw] = useState('');
  const [cookies, setCookie, removeCookie] = useCookies(["rememberUserId", "autoUserId", "autoUserPw"]);
  const [isRemember, setIsRemember] = useState(false);

4. useEffect Hook 작성

  useEffect(() => {
    if (cookies.rememberUserId !== undefined) {
      setUserId(cookies.rememberUserId);
      // setUserId 함수를 호출하여 state 변수인 userId의 값을 cookies.rememberUserId로 설정
      setIsRemember(true);
      // state 변수인 setIsRemember 값을 true로 설정
    }
  }, [cookies.rememberUserId]);
  // rememberUserId 값이 변경될 때만 useEffect 함수가 실행되도록 설정한다.
  // 이렇게 하면 불필요한 state 업데이트를 방지할 수 있음

5. id저장 handler 작성

  const handleRemember = (e) => {
    setIsRemember(e.target.checked); // isRemember의 상태를 체크박스의 체크 여부와 일치시킴
    if (!e.target.checked) { // 체크박스가 체크되어 있지 않다면,
      removeCookie('rememberUserId'); // 쿠키 삭제
    } else if(isRemember){ // 체크박스가 체크되어있고, isRemember이 true라면
      setCookie("rememberUserId", userId, { path: '/', expires: new Date(Date.now() + 604800000) });
    }
  };

6. login handler 작성

  const handleLogin = () => {
    if(userId === "") {
      alert("아이디를 입력해주세요.");
    } else if (userPw === "") {
      alert("비밀번호를 입력해주세요.")
    } else {
      axios.post('/auth/login', {
        userId: userId,
        userPw: userPw,
      })
      .then(function(obj) {
        localStorage.setItem("refresh_token", obj.data.data.authToken);
        const config = {
          headers: {
            Authorization: `${localStorage.getItem("refresh_token")}`,
          },
        };
        axios.get('/try', config)
          .then(function (response) {
            console.log("refresh_token 값 : " + response.data);
            alert(userId + "님 환영합니다.");
            setIsRemember(true); // 체크박스에 체크가 되어있다면
            setCookie("rememberUserId", userId, { path: '/', expires: new Date(Date.now() + 604800000) });
            setAutoLogin(true);
            window.location.href = "/";
          })
          .catch(function (error) {
            console.log("오류 " + error);
          });
        })
      .catch(() => {
        alert("아이디 또는 비밀번호를 잘못 입력했습니다. 입력하신 내용을 다시 확인해주세요.")
      })
    }
    
  };

- 여기서 5번과 6번에 setCookie를 왜 두번해주는지 이해가 되지 않아 찾아보니..

- 먼저 handlerRemeber함수에서 실행되고, isRemember(체크박스가)가 true면 쿠키에 rememberUSerId가 저장되어야하기 때문

- 그러나 이거는 첫 번째 페이지 로드시에만 실행되므로, 이후 새로고침되거나 페이지가 이동될 때 유지되지가 않음

- 그래서 handlerLogin에서 (로그인이 완료된 시점에서) 실행 되는 setCookie를 해줘야 한다.

- 이거는 새로고침이나 페이지 이동후에도 로그인 정보를 유지하기 위해 사용된다.

 

7. js 작성

<Box>
    <TextField
      type="text"
      label="아이디"
      value={userId}
      onChange={(e) => setUserId(e.target.value)}
      variant="standard"
    />
            
    <TextField
      type="password"
      label="패스워드"
      value={userPw}
      onChange={(e) => setUserPw(e.target.value)}
      variant="standard"
    />

    <LoginButton />

    <FormControlLabel
      control={<Checkbox />}
      label="ID 저장"
      checked={isRemember}
      onChange={handleRemember}
    />
</Box>

 

■ 최종코드

더보기
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import Div from './api/reactive.js'
import { useCookies } from 'react-cookie';

// mui
import Button from '@mui/material/Button';
import TextField from '@mui/material/TextField';
import Box from '@mui/material/Box';
import theme from "./api/theme";
import styled, { ThemeProvider } from "styled-components";
import PersonIcon from '@mui/icons-material/Person';
import VpnKeyIcon from '@mui/icons-material/VpnKey';
import { InputAdornment, Checkbox, FormControlLabel  } from '@mui/material';


// 1. 레이아웃 디자인
const StyleDivText = styled.p`
  color: rgb(117, 117, 117);
  font-size: 20px;
  font-weight: 500;
  text-align: center;
`;
const StyleDiv = styled.div`
  margin: 15% 0 25% 0;
`;
const StyleButton = styled(Button)`
  background: rgb(62, 128, 234) !important;
  color: white !important;
  border-radius: 15px !important;
  height: 50px;
  margin: 30px 0 10px 0 !important;
`;

function Login() {

  // 1. useState
  const [userId, setUserId] = useState('');
  const [userPw, setUserPw] = useState('');
  const [cookies, setCookie, removeCookie] = useCookies(["rememberUserId", "autoUserId", "autoUserPw"]);
  const [isRemember, setIsRemember] = useState(false);

  useEffect(() => {
    if (cookies.rememberUserId !== undefined) {
      setUserId(cookies.rememberUserId);
      setIsRemember(true);
    }
  }, [cookies.rememberUserId]);

  // 2. Id 기억하기
  const handleRemember = (e) => {
    setIsRemember(e.target.checked);
    if (!e.target.checked) {
      removeCookie('rememberUserId');
    } else if(isRemember){
      setCookie("rememberUserId", userId, { path: '/', expires: new Date(Date.now() + 604800000) });
    }
  };

  // 3. handle Login
  const handleLogin = () => {
    if(userId === "") {
      alert("아이디를 입력해주세요.");
    } else if (userPw === "") {
      alert("비밀번호를 입력해주세요.")
    } else {
      axios.post('/auth/login', {
        userId: userId,
        userPw: userPw,
      })
      .then(function(obj) {
        localStorage.setItem("refresh_token", obj.data.data.authToken);
        const config = {
          headers: {
            Authorization: `${localStorage.getItem("refresh_token")}`,
          },
        };
        axios.get('/try', config)
          .then(function (response) {
            console.log("refresh_token 값 : " + response.data);
            alert(userId + "님 환영합니다.");
            setIsRemember(true);
            setCookie("rememberUserId", userId, { path: '/', expires: new Date(Date.now() + 604800000) });
            setAutoLogin(true);
            window.location.href = "/";
          })
          .catch(function (error) {
            console.log("오류 " + error);
          });
        })
      .catch(() => {
        alert("아이디 또는 비밀번호를 잘못 입력했습니다. 입력하신 내용을 다시 확인해주세요.")
      })
    }
    
  };

  // 4. Login Button
  function LoginButton() {
    return <StyleButton
        onClick={handleLogin}
        fullWidth
      >로그인</StyleButton>
  }

  return (

    <Box>
      <ThemeProvider theme={theme}>
        <Div>
          <form>
            <TextField
              type="text"
              label="아이디"
              margin="normal"
              value={userId}
              onChange={(e) => setUserId(e.target.value)}
              fullWidth
              variant="standard"
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start" >
                    <PersonIcon />
                  </InputAdornment>
                ),
              }}
            />
            
            <TextField
              type="password"
              label="패스워드"
              margin="normal"
              value={userPw}
              onChange={(e) => setUserPw(e.target.value)}
              autoComplete="on"
              fullWidth
              variant="standard"
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <VpnKeyIcon />
                  </InputAdornment>
                ),
              }}
            />

            <LoginButton />

            <FormControlLabel
              control={<Checkbox />}
              label="ID 저장"
              checked={isRemember}
              onChange={handleRemember}
            />

            <FormControlLabel
              control={<Checkbox />}
              label="자동 로그인"
              checked={autoLogin}
              onChange={handleAutoLogin}
            />

          </form>
        </Div>
      </ThemeProvider>
    </Box>
    
    );
}

export default Login;

 

반응형