로그인 세부 구현 - 창우

  1. 로그인 요청: 클라이언트가 사용자 자격 증명(예: 사용자 이름, 비밀번호)을 백엔드로 전송합니다.
  2. 토큰 발급: 백엔드는 자격 증명이 올바르면 액세스 토큰과 리프레시 토큰을 생성하여 클라이언트에 반환합니다.
  3. 토큰 저장: 클라이언트는 액세스 토큰을 상태 관리(store)에 저장하고, 리프레시 토큰을 안전한 저장소(localStorage 등)에 저장합니다.

로그인 이후 페이지가 처음 렌더링될 때 로그인 여부를 검증하는 과정은 다음과 같습니다:

1. 페이지 렌더링 시 로그인 여부 검증

javascript코드 복사
// 예시: 페이지가 처음 렌더링될 때
async function checkLoginStatus() {
  const accessToken = useAuthStore.getState().accessToken;
  const response = await fetch('/api/check-auth', {
    headers: { 'Authorization': `Bearer ${accessToken}` },
  });

  if (response.status === 200) {
    // 로그인 상태 유지
  } else if (response.status === 401) {
    // 토큰이 만료되었을 경우
    await refreshAccessToken();
    // 새 액세스 토큰을 얻은 후 다시 로그인 상태를 확인
    await checkLoginStatus();
  } else {
    // 기타 오류 처리
  }
}

2. 액세스 토큰 검증

javascript코드 복사
// 백엔드 예시: 토큰 검증 미들웨어
function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];

  if (!token) return res.sendStatus(401);

  jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
}

3. 액세스 토큰이 만료된 경우

javascript코드 복사
async function refreshAccessToken() {
  const refreshToken = localStorage.getItem('refreshToken');
  const response = await fetch('/api/token', {
    method: 'POST',
    body: JSON.stringify({ token: refreshToken }),
    headers: { 'Content-Type': 'application/json' },
  });

  const data = await response.json();
  if (response.status === 200) {
    const { accessToken } = data;
    useAuthStore.getState().setAccessToken(accessToken);
  } else {
    // 리프레시 토큰도 유효하지 않은 경우 로그아웃 처리
    logout();
  }
}

4. 새로운 액세스 토큰 발급

javascript코드 복사
// 백엔드 예시: 리프레시 토큰을 사용한 액세스 토큰 재발급
app.post('/api/token', (req, res) => {
  const { token } = req.body;
  if (!token) return res.sendStatus(401);

  jwt.verify(token, process.env.REFRESH_TOKEN_SECRET, (err, user) => {
    if (err) return res.sendStatus(403);

    const accessToken = generateAccessToken({ name: user.name });
    res.json({ accessToken });
  });
});

요약