[인증 / 보안] Token, OAuth2.0

챔수·2023년 5월 4일
0

개발 공부

목록 보기
55/100

1. Token 과제

토큰 과제를 통해 토큰을 어떤식으로 가져와 사용하는지에 대해 알아봤다.

login

module.exports = async (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) {
    // userInfo.id값이 저장되 데이터와 다르면 401, Not Authorized 메세지
    res.status(401).send("Not Authorized");
  }

  const { accessToken, refreshToken } = generateToken(
    userInfo,
    checkedKeepLogin
  );
  // generateToken()의 인자로 저장된 데이터와 로그인데이터가 일치하는 필터된 userInfo, 로그인 유지할 버튼인 checkedKeepLogin를 넣어주고
  // 구조분해할당으로 accessToken, refreshToken를 넣어주는데 checkedKeepLogin이 참인경우(체크 되있는 경우) 만 들어가게 만듬

  if (refreshToken) {
    // 만약 refreshToken이 참이면 (checkedKeepLogin이 눌러져 있으면) 쿠키에 refreshToken을 추가하고 7일 뒤 제거되게 함.
    res.cookie("refresh_jwt", refreshToken, {
      domain: "localhost",
      path: "/",
      sameSite: "strict",
      httpOnly: true,
      secure: true,
      expires: new Date(Date.now() + 24 * 3600 * 1000 * 7), // 7일 후 소멸되는 Persistent Cookie
    });
  }
  res.cookie("access_jwt", accessToken, {
    // 걸러야할 경우를 다 걸렀으니 쿠키에 accessToken을 넣어줌.
    domain: "localhost",
    path: "/",
    sameSite: "strict",
    httpOnly: true,
    secure: true,
    // Expires 옵션이 없는 Session Cookie
  });
  return res.redirect("/userinfo"); // /userinfo로 리다이렉트
};

userInfo

module.exports = async (req, res) => {
  const accessToken = req.cookies["access_jwt"];
  const refreshToken = req.cookies["refresh_jwt"];
  const accessPayload = verifyToken("access", accessToken);

  if (accessPayload) {
    // verifyToken함수를 통해 access토큰 이 있는지 없는지 판별
    const userInfo = {
      ...USER_DATA.filter((user) => user.id === accessPayload.id)[0],
    }; // 유저의 데이터와 access토큰을 가지고있는지 없는지 필터
    if (!userInfo) {
      // 들어온 유저가 access토큰이 없을때
      return res.status(401).send("Not Authorized");
    }
    delete userInfo.password;
    return res.json(userInfo);
  } else if (refreshToken) {
    // 아니고 만약 refresh토큰만 가지고 있을때
    const refreshPayload = verifyToken("refresh", refreshToken);

    if (!refreshPayload) {
      // 가지고 있는 refresh토큰 거짓일때(서버에서 내려준 토큰이 아닐때)
      return res.status(401).send("Not Authorized");
    }

    const userInfo = USER_DATA.filter(
      (user) => user.id === refreshPayload.id
    )[0];
    const { accessToken } = generateToken(userInfo);

    res.cookie("access_jwt", accessToken, {
      // 걸러질 부분을 다 걸러주고 서버에서 내려준 refresh토큰이 있을 경우 access토큰을 추가해 로그인이 진행될 수 있게 함.
      domain: "localhost",
      path: "/",
      sameSite: "strict",
      httpOnly: true,
      secure: true,
      // Expires 옵션이 없는 Session Cookie
    });

    return res.json({ ...userInfo, password: undefined });
  }
  return res.status(401).send("Not Authorized");
};

2. OAuth2.0

과거 어떤 사이트를 이용하고 싶을때마다 그 사이트에 정보를 입력하는 것이 아닌 OAuth인증은 사용자 정보를 가지고 있는 웹 사이트(Naver, Kakao, Google 등과 같이 이용자가 많은 대형 웹 사이트)에서 사용자의 인증을 대신 해주고, 접근 권한에 대한 토큰을 발급한 후, 이를 이용해 서버에서 인증하고 로그인하는 방식이다.

OAuth2.0 과제 인증 흐름

과제에서 OAuth App을 통해 Access token을 받아오는 과정은 다음과 같다.

profile
프론트앤드 공부중인 챔수입니다.

0개의 댓글