React

React + Express(Node) + JWT를 이용한 로그인, 회원가입 구현하기

milliwonkim 2022. 9. 12. 22:39
반응형
SMALL

프로젝트 구조

Client: React

Backend: Express

Token Management: JWT

 

주요 기능만 블로그에 적고

구체적인 코드는 소스코드에 적어두겠습니다

Client

// client/src/services/api.js

import axios from "axios";

export const api = axios.create({
  // express 서버가 띄워져있는 주소
  baseURL: "http://localhost:4000",
  // withCredentials를 true로 해야 refreshToken cookie를 주고 받을 수 있다
  withCredentials: true
});
// client/src/services/authHeader.js

export default function authHeader() {
  const user = JSON.parse(localStorage.getItem("user"));
  console.log("user", user);
  if (user && user.accessToken) {
    return { Authorization: "Bearer " + user.accessToken };
  } else {
    return {};
  }
}
// client/src/services/authService.js

import { api } from "./api";

const API_URL = "/auth";

const signup = (email, password) => {
  return api
    .post(API_URL + "/signup", {
      email,
      password,
    })
    .then((response) => {
      if (response.data.accessToken) {
        // user라는 key로 accessToken, refreshToken을 localStorage에 저장함
        // accessToken이 있다면
        // 이를 localStorage에 담아서 로그인 상태를 expires 기간까지 유지
        
        // 여기 안에 expires 기간도 적혀있음
        // expires 기간이 지나면 만료됨
        localStorage.setItem("user", JSON.stringify(response.data));
      }

      return response.data;
    });
};

const login = (email, password) => {
  return api
    .post(API_URL + "/login", {
      email,
      password,
    })
    .then((response) => {
      if (response.data.accessToken) {
      	// accessToken이 있다면
        // 이를 localStorage에 담아서 로그인 상태를 expires 기간까지 유지
        localStorage.setItem("user", JSON.stringify(response.data));
      }

      return response.data;
    });
};

const logout = () => {
  localStorage.removeItem("user");
};

const getCurrentUser = () => {
  return JSON.parse(localStorage.getItem("user"));
};

const AuthService = {
  signup,
  login,
  logout,
  getCurrentUser,
};

export default AuthService;
// client/src/services/postService.js

import { api } from "./api";
import authHeader from "./authHeader";

const API_URL = "/posts";

const getAllPublicPosts = () => {
  return api.get(API_URL + "/public");
};

const getAllPrivatePosts = () => {
  // header에 authHeader를 담아서
  // 로그인 토큰 정보를 보낸다.
  return api.get(API_URL + "/private", { headers: authHeader() });
};

const postService = {
  getAllPublicPosts,
  getAllPrivatePosts,
};

export default postService;

 

Backend

// backend/routes/posts.js

// authToken 미들웨어를 통과해서 privatePosts를 리턴할 수 있다
router.get("/private", authToken, (req, res) => {
  res.json(privatePosts);
});
// backend/middleware/authToken.js

const jwt = require("jsonwebtoken");
require("dotenv").config();

const authToken = async (req, res, next) => {
  // Option 1
  const authHeader = req.headers["authorization"];
  const token = authHeader && authHeader.split(" ")[1]; // Bearer Token

  // Option 2
  // const token = req.header("x-auth-token");

  if (!token) {
    res.status(401).json({
      errors: [
        {
          msg: "Token Not Found",
        },
      ],
    });
  }

  try {
  	// process.env.ACCESS_TOKEN_SECRET은 
    // backend 폴더의 root에 .env 파일을 만들어서 적용
    const user = await jwt.verify(token, process.env.ACCESS_TOKEN_SECRET);
    req.user = user.email;
    next();
  } catch (err) {
    res.status(403).json({
      errors: [
        {
          msg: "invalid token",
        },
      ],
    });
  }
};

module.exports = authToken;

 

소스코드: https://github.com/milliwonkim/react-express-jwt-auth/tree/auth/react-auth

 

GitHub - milliwonkim/react-express-jwt-auth

Contribute to milliwonkim/react-express-jwt-auth development by creating an account on GitHub.

github.com

 

반응형
LIST