
모바일 환경에서 Refresh Token 저장 방식 변경 (Third-Party Cookie 이슈)
MERN 스택으로 제작한 TODO 앱을 완성하고 배포를 했는데 모바일 환경에서 로그인이 되지 않는 문제를 발견했습니다.확인해보니 데스크탑에서는 정상적으로 로그인되었지만, 모바일에서는 리프레시 토큰이 쿠키에 저장되지 않는 것이 원인이었습니다.검색해보니 iOS 14부터는 개인정보 보호 정책으로 인해 Third-Party Cookie 사용이 제한되어, sameSite: None 설정을 유지하면 쿠키가 저장되지 않는다는 것을 확인했습니다.안드로이드 환경에서는 테스트해보진 않았지만, 같은 문제가 발생할 가능성이 있어 수정이 필요하다고 판단했습니다.해결책을 찾아봤지만, sameSite를 Lax 또는 Strict로 변경하는 것 외에는 방법이 없는 거 같습니다.하지만 도메인이 없는 상태에서는 sameSite 옵션을 변..

Google 로그인 구현 (OAuth 2.0 + JWT + Zustand)
MERN todo 프로젝트에서 Google OAuth 2.0을 활용한 로그인 기능을 구현했습니다.@react-oauth/google 라이브러리를 활용하여 클라이언트에서 Google 로그인 버튼을 만들고, 서버에서는 Google API를 이용해 사용자 정보를 받아와 JWT를 발급하는 방식으로 처리했습니다.1. Google OAuth 로그인 흐름클라이언트에서 useGoogleLogin 훅을 이용해 Google 로그인 요청@react-oauth/google 라이브러리에서 제공하는 useGoogleLogin 훅을 사용했습니다.이 훅을 이용하면 Google 로그인 창을 띄우고, 로그인 성공 시 code를 반환받을 수 있습니다.Google에서 code를 반환하면 이를 서버로 전송code는 Google OAuth 서..

JWT 인증 방식 개선: 쿠키 기반에서 토큰 기반으로 전환
기존에는 JWT를 이용해 Access Token을 생성한 후 쿠키에 저장하여 인증하는 방식으로 로그인 및 Todo 관련 API를 Protected Route 로 처리하였습니다. 하지만 정보를 찾아본 결과 쿠키 기반 인증 방식에는 보안 취약점이 있기 때문에 이를 개선하고자 토큰 기반 인증 방식으로 변경하였습니다.쿠키 기반 인증의 보안 문제쿠키는 오랜 시간 유지될 수 있음 → 토큰이 탈취되면 장기간 악용될 가능성이 있음자바스크립트로 쿠키 접근 가능 → XSS(Cross-Site Scripting) 공격에 취약함CSRF(Cross-Site Request Forgery) 공격 가능 → 악성 사이트에서 사용자의 인증된 요청을 위장할 수 있음이러한 이유로 보안상 쿠키 기반 인증은 많이 사용되지 않는 방식이라고 합니..

회원가입 및 로그인 기능 구현
회원가입 및 로그인 기능을 클라이언트에서 구현한 내용을 정리해보겠습니다.1. 회원가입 기능 구현회원가입 기능은 useActionState를 활용하여 서버 요청과 응답을 관리하도록 구현했습니다.회원가입 요청을 보낼 때 상태를 관리하고, 성공 또는 실패 여부를 사용자에게 보여줄 수 있도록 했습니다.1-1. 회원가입 컴포넌트import { useActionState, useEffect, useState } from 'react';import { Eye, EyeOff, UserRound } from 'lucide-react';import { Input } from '@/components/ui/input';import { Button } from '@/components/ui/button';import { re..

Todo CRUD API 구현하기
이번 글에서는 Todo CRUD 기능을 구현한 내용을 정리했습니다.사용자의 할 일 목록을 추가, 조회, 수정, 삭제할 수 있도록 API를 만들었습니다.1. 전체 목록 조회 (GET /todos)export async function getAllTodos(req, res, next) { await connectToDB(); const todos = await Todo.find({ userID: req.user.id }); res.status(200).send(todos);}find({ userID: req.user.id })를 사용해 해당 유저의 todo만 조회한다.2. 할 일 추가 (POST /todos)export async function addTodo(req, res, next) {..

쿠키 기반 JWT 인증 및 로그인/로그아웃 기능
쿠키를 활용한 JWT 기반 로그인, 로그아웃 기능을 구현하고 이를 검증하는 인증 미들웨어를 적용했습니다.우선 app.js에 req.cookies에 접근할 수 있도록 cookie-parser 미들웨어를 추가해야 합니다.import cookieParser from 'cookie-parser';app.use(cookieParser());1. 로그인 및 로그아웃 구현1-1. 로그인export async function login(req, res, next) { const data = req.body; if (!data?.email) { return next(createError(400, '이메일을 입력해주세요.')); } if (!data?.password) { r..