티스토리 뷰
오늘은 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
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
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
- 인적성
- BFS
- 감정일기장
- SEB43
- Redux
- 코드스테이츠
- dfs
- SEB 43
- 그리디 알고리즘
- 개인 프로젝트
- 프리프로젝트
- dictionary
- React quill
- SEB 43기
- 프로그래머스
- Python
- useContext
- 기술면접
- seb
- 코테
- 프론트엔드
- 백준
- 회고
- 감정 일기장
- 프로젝트
- 다이나믹 프로그래밍
- SEB43기
- 스택오버플로우
- 브루드포스
- til
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |