티스토리 뷰

cookie 튜토리얼

CORS 설정

CORS 설정은 이러한 Same-Origin Policy를 우회하기 위해 서버에서 브라우저에게 특정 출처에서 자원에 대한 액세스를 허용하도록 허용하는 메커니즘입니다. 이를 통해, 다른 출처의 자원을 안전하게 사용

const corsOptions = {

	// client는 http://localhost:3000 을 이용
  origin: "http://localhost:3000",

	// cookie는 인증 정보를 포함하는 경우가 많으므로 credentials도 설정
    //credentials 속성은 자격 증명 정보를 포함하는 요청을 허용할지 여부를 결정
  credentials: true,

	// 허용할 메소드를 배열에 담아서 작성
  methods: ['GET', 'POST', 'OPTION']

};

flow 이해

1.client : 버튼 클릭하면 서버로 로그인 요청을 보내기 

2.server :  로그인 요청 처리(회원가입 되어있는지 확인)

회원이면 응답에 쿠키와 회원정보 담아서 전달

3. client : 응답을 받아 react상태 업데이트

4. client : 화면 리렌더링

로그인 유지 옵션 체크 => 서버에서 받아온 쿠기를 사용해서 회원정보 받아옴 ,쿠키 유지 시간만큼 자동 로그인 유지

 

5. client : 로그아웃 버튼 눌러 서버로 로그아웃 요청을 보내기

6.server : 로그아웃 요청 처리(쿠키 삭제 후 클라이언트로 응답 보냄)

7. client : 응답이 들어오면 react 상태 초기화

8. client : 화면 리렌더링 => 로그인 페이지

 

client 측

Login,js

일부

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 = () => {
   
    if (!loginInfo.userId || !loginInfo.password) {
      setErrorMessage('아이디와 비밀번호를 입력하세요')
      // 입력되지 않은 값으로 요청을 보내볼 필요도 없이 바로 리턴
      return;
    } else{
      setErrorMessage('');
    }
    return axios
      .post("http://localhost:4000/login", {loginInfo, checkedKeepLogin})
      /*login을 담당하는 endpoint*/
      .then((res) => {
       /* 로그인에 성공했다면 응답으로 받은 데이터가 Mypage에 렌더링되도록 State를 변경*/
       console.log(res.data)
       setUserInfo(res.data)
        setIsLogin(true)

				//여기에서 에러 초기화
        setErrorMessage("")
      })
      .catch((err) =>    
       console.log(err.response.data)
       if (err.response.status === 401) {
       setErrorMessage("로그인에 실패했습니다.")
       }
       
      });
     
     
   
  };
  :
  :

Mypage

일부

export default function Mypage({ userInfo, setIsLogin, setUserInfo }) {
  const logoutHandler = () => {
    

    return axios
      .post("http://localhost:4000/logout")
      .then((res) => {

      setUserInfo(null);
      setIsLogin(false);
      })
      .catch((err) => {
    
     alert(err);
      });
    
  };
  :
  :
  //로그아웃 버튼 누를 시 userInfo는 null , isLogin는 false가 된다.

App.js

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

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

      if (err.response.status === 401) {
        console.log(err.response.data);
      }
      });
    
  };

  useEffect(() => {
   
    authHandler();
  }, []);

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

export default App;

server 측

login.js

onst { USER_DATA } = require('../../db/data');

module.exports = (req, res) => {
  const { userId, password } = req.body.loginInfo;
  const { checkedKeepLogin } = req.body;
  const userInfo = {
    ...USER_DATA.filter((user) => user.userId === userId && user.password === password)[0],
  };
  console.log(req.body)

 
   //로그인 성공 시에는 클라이언트에 쿠키를 전송
   //쿠키의 cookieId에는 userInfo.id가 담겨야 된다.
   
  console.log(userInfo)
  
  var cookiesOption = { 
    domain: 'localhost',
	path: '/',
	
	httpOnly: true,
	sameSite: 'none',
	secure: true,
}

if (userInfo.id === undefined) {
  res.status(401).send('Not Authorized')
}
else if (checkedKeepLogin === true) {
	
	cookiesOption.maxAge = 1000 * 60 * 30
	//30분동안 쿠키를 유지

	cookiesOption.expires = new Date(Date.now() + (1000 * 60 * 30) )
	// 지금 시간 + 30분 후에 쿠키를 삭제한다는 의미

	res.cookie('cookieId', userInfo.id, cookiesOption)
  res.redirect("/userinfo")

} else {
	
	res.cookie('cookieId', userInfo.id, cookiesOption)
  res.redirect("/userinfo")
}




};

userinfo.js

const { USER_DATA } = require('../../db/data');

module.exports = (req, res) => {

  const cookieId = req.cookies.cookieId
  const userInfo = {
    ...USER_DATA.filter((user) => user.id === cookieId)[0],
 };
 if (!cookieId || !userInfo.id){
  res.status(401).send('Not Authorized');
} else {
  // 비밀번호는 민감한 정보라서 삭제 후에 보내야 합니다.
  delete userInfo.password
  res.send(userInfo)
}

};

logout.js

module.exports = (req, res) => {
  
  //cookie-parser의 clearCookie('쿠키의 키', cookieOption) 메서드로 해당 키를 가진 쿠키를 삭제
 
 const cookiesOption = {
    domain: 'localhost',
    path: '/',
    httpOnly: true,
    sameSite: 'none',
    secure: true,
  }
  res.status(205).clearCookie('cookieId', cookiesOption).send("logout")
};

Session 튜토리얼

 

서버측

login.js

const { USER_DATA } = require('../../db/data');
module.exports = (req, res) => {
  const { userId, password } = req.body.loginInfo;
  const { checkedKeepLogin } = req.body;
  const userInfo = {
    ...USER_DATA.filter((user) => user.userId === userId && user.password === password)[0],
  };
 
  if (!userInfo.id) {
    res.status(401).send("Not Authorized")
  } else if (checkedKeepLogin) {
    req.session.sessionId = userInfo.id
  

    console.log(req.session)
  
    req.session.cookie.maxAge = 1000 * 60 * 30
  
    res.redirect('/userinfo')
        
  } else {
    req.session.sessionId = userInfo.id
    res.redirect('/userinfo')
  }
};

userinfo.js

const { USER_DATA } = require('../../db/data');

module.exports = (req, res) => {

  const sessionId = req.session.sessionId
const userInfo = {
  ...USER_DATA.filter((user) => user.id === sessionId)[0],
};

if (!sessionId || !userInfo.id){
  res.status(401).send('Not Authorized');
} else {
  delete userInfo.password
  res.send(userInfo)
}
};

logout.js

module.exports = (req, res) => {

  req.session.destroy();
  res.status(205).send('Logged Out Successfully');
};

 

'codestates > section3' 카테고리의 다른 글

과제 - Tokens 과 OAuth2.0  (0) 2023.03.08
과제 - 웹 표준 & 접근성 개선  (0) 2023.03.02
알고리즘rotatedArraySearch  (0) 2023.03.02
알고리즘power  (0) 2023.02.28
SEO에 영향을 미치는 요소  (0) 2023.02.28
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/09   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함