티스토리 뷰

코드스테이츠

TIL 23.03.09

_Yunhwan 2023. 3. 9. 15:53

오늘은 OAuth에 대해 배우고, 관련 실습을 진행하였다.

 

OAuth

인증을 중개해주는 메커니즘

보안된 리소스에 액세스하기 위해 클라이언트에게 권한을 제공하는 프로세스를 단순화하는 프로토콜

(ex google, github, facebook 로그인)

 

 

실습

구현 단계는 아래와 같다

 

우선 실습전에, 

https://github.com/settings/developers

 

위의 링크에서 OAuth 앱을 등록해 주었다.

 

개발환경에서 진행했기 때문에,

Authorization callback URL을 (http://localhost:3000)로 리디렉션하였다.

그리고 ClientId와 ClientSecret을 서버에 저장하여 사용하였다.

 

 

로그인

 

클라이언트 Login.js    

 

로그인 버튼을 클릭시, GitHub로부터 사용자 인증을 위해 GitHub로 이동해 주었다.

  const loginRequestHandler = () => {

    return window.location.assign(
      `https://github.com/login/oauth/authorize?client_id=${CLIENT_ID}`
    );
  };

 

클라이언트 App.js    

 

OAuth 인증 시, Authorization Server로부터 Authorization Code를 파라미터로 받은 후

서버의 callback url로 Authorization Code를 전달하고, AccessToken을 발급받는다.

  const getAccessToken = async (authorizationCode) => {

    // Authorization Code를 서버로 보내주고 서버에서 Access Token 요청
    return await axios
      .post("http://localhost:4000/callback", { authorizationCode })
      .then((res) => {
        setAccessToken(res.data.accessToken);
        setIsLogin(true);
      });
  };
  useEffect(() => {
    // Authorization Server로부터 클라이언트로 리디렉션된 경우, Authorization Code가 함께 전달

    const url = new URL(window.location.href);
    const authorizationCode = url.searchParams.get("code");
    if (authorizationCode) {
      getAccessToken(authorizationCode);
    }
  }, []);

 

서버 -callback.js

authorization code를 이용해 access token을 발급받기 위한 post를 보내고,
부여된 access token을 클라이언트로 응답해준다.
  try {
    const result = await axios({
      method: "post",
      url: `https://github.com/login/oauth/access_token`,
      headers: {
        accept: "application/json",
      },
      data: {
        client_id: CLIENT_ID,
        client_secret: CLIENT_SECRET,
        code: req.body.authorizationCode,
      },
    });

    const accessToken = result.data.access_token;

    return res.status(200).send({ accessToken });
  } catch (err) {
    return res.status(401).send({ message: "error" });
  }

 

클라이언트 - MyPage.js

 

accesToken을 받았다면 로그인이 된 상태로 간주하고, MyPage로 이동한다.

props로 전달받은 access token을 이용해 /userinfo 엔드포인트로 요청하여 사용자의 정보를 받아온다.

 

  useEffect(() => {

    // Access Token을 이용해 /userinfo 엔드포인트로 요청
    if (accessToken) {
      axios
        .post("http://localhost:4000/userInfo", { accessToken })
        .then((res) => {
          setGithubUser(res.data.githubUserData);
          setServerResource(res.data.serverResource);
          setIsLoading(false);
        });
    }
  }, []);

 

서버- userInfo.js

 

  클라이언트에서 전달받은 access token를 이용해,
  Resource Server에 요청하여 사용자의 정보를 받아와 클라이언트에 전달한다.

  // 클라이언트에서 전달받은 access token를 이용해
  // Resource Server에 요청하여 사용자의 정보를 가져옵니다.
  return axios
    .get("https://api.github.com/user", {
      headers: {
        Authorization: `token ${accessToken}`,
      },
    })
    .then((res) => res.data)
    .then((githubUserData) => {
      res.send({ githubUserData, serverResource });
    })
    .catch((e) => {
      res.sendStatus(403);
    });

 

 

로그아웃

클라이언트-logout.js

 

로그아웃 버튼 클릭 시, Access Token을 이용해 /logout 엔드포인트로 요청

const logoutHandler = () => {

    // Access Token을 이용해 /logout 엔드포인트로 요청

    if (accessToken) {
      return axios
        .delete("http://localhost:4000/logout", { data: { accessToken } })
        .then((res) => setIsLogin(false));
    }
  };

 

 

서버-logout.js

클라이언트에서 전달받은 access token를 이용해 사용자의 권한 부여를 취소
 axios
    .delete(`https://api.github.com/applications/${CLIENT_ID}/token`, {
      data: {
        access_token: accessToken,
      },
      auth: {
        username: CLIENT_ID,
        password: CLIENT_SECRET,
      },
    })
    .then(() => {
      res.status(205).send("Successfuly Logged Out");
    })
    .catch((e) => {
      console.log(e.response);
    });

 

 

결과물

'코드스테이츠' 카테고리의 다른 글

TIL 23.03.13 & Section3 회고  (0) 2023.03.13
기술면접 준비 -  (0) 2023.03.13
TIL 23.03.08  (0) 2023.03.08
TIL 23.03.07  (0) 2023.03.08
TIL 23.02.24  (0) 2023.02.24
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
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
글 보관함