-
Notifications
You must be signed in to change notification settings - Fork 5
Whale Extension에서 OAuth 적용하기
Donghyun Kim edited this page Dec 16, 2020
·
2 revisions
→ Whale Extension 환경에서 OAuth (네이버 소셜 로그인) 적용하기
- Extension 환경에서는 url이 없으므로 일반적인 웹 OAuth 방식을 사용할 수 없다 🙄
- 그렇게 방법을 찾아보던 중, Chrome에서 제공해주는 identity 라는 API를 사용하면 OAuth2 access tokens를 얻을 수 있다는 사실을 알게 되었다 😀
- 하지만 Whale 환경에서는 많고 많은 API 중, identity만 지원을 하지 않는다......... 😧
- 그러면 Chrome identity api를 직접 구현해 보는 건 어떨까?
- 로그인 버튼을 클릭하면 background.js 파일에 'login' 이라는 message를 전송
- message를 받은 background.js는 유저 정보를 담아 sendResponse를 통해 반환
-
로그인 버튼을 클릭하면 background.js 파일에 'login' 이라는 message를 전송
-
네이버 API에 code와 redirect url이 담긴 새로운 팝업 창 생성 (2, 3번 과정)
chrome.windows.create(
{
url:
'https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URL}',
type: 'popup',
},
() => {
chrome.tabs.onUpdated.addListener(chromeEvnet);
}
);
- chrome.tabs.onUpdated 함수를 통해 변경된 탭 감지 이벤트 등록
https://nid.naver.com/oauth2.0 url 에 요청을 보내면 code값이 포함된 redirect url으로 팝업 창이 바뀌는 과정에서, tabs.onUpdated 함수가 변경을 감지
- redirect url에서 code값 추출 후, server에 code값 전송 (4번 과정)
const chromeEvnet = (tabId, changeInfo, tab) => {
const redirect_url = changeInfo.url;
if (redirect_url && redirect_url.includes('code=')) {
chrome.tabs.remove(tabId, () => {});
const code = redirect_url.split('code=')[SECOND_ELEM_INDEX].split('&')[FIRST_ELEM_INDEX];
const body = { code: code };
fetch('https://www.formulachef.tk/api/auth/login', {
method: 'POST',
body: JSON.stringify(body),
headers: {
'Content-Type': 'application/json',
},
})
.then((res) => res.json())
.then((data) => {
sendResponse(data);
chrome.tabs.onUpdated.removeListener(chromeEvnet);
});
}
-
server에서는 code값을 통해 access token을 반환받음 (5,6,7,8번 과정)
-
유저 정보를 DB에 저장 후, client에 유저 정보를 반환해줌 (9번 과정)
-
sendResponse를 통해 content script에 data를 넘겨줌 (10번 과정)
sendResponse(data);
- tabs.onUpdated.removeListener 함수를 통해 이전에 만들었던 팝업 창 삭제
chrome.tabs.onUpdated.removeListener(chromeEvnet);
// useSaveButtons
chrome.runtime.sendMessage({ message: 'login' }, (response) => {
if (response.error) {
setLoginMessage(LoginMessage.LOGIN_FAUILRE);
}
if (response.results) {
const { userToken, userId } = response.results;
setToken(userToken);
dispatch(userLogin(userId));
dispatch(getFavoritesThunk(userId));
setLoginMessage(LoginMessage.LOGIN_SUCCESS);
}
}
// background.js
const FIRST_ELEM_INDEX = 0;
const SECOND_ELEM_INDEX = 1;
whale.runtime.onMessage.addListener((message, sender, sendResponse) => {
const chromeEvnet = (tabId, changeInfo, tab) => {
const redirect_url = changeInfo.url;
if (redirect_url && redirect_url.includes('code=')) {
chrome.tabs.remove(tabId, () => {});
const code = redirect_url.split('code=')[SECOND_ELEM_INDEX].split('&')[FIRST_ELEM_INDEX];
const body = { code: code };
fetch('https://www.formulachef.tk/api/auth/login', {
method: 'POST',
body: JSON.stringify(body),
headers: {
'Content-Type': 'application/json',
},
})
.then((res) => res.json())
.then((data) => {
sendResponse(data);
chrome.tabs.onUpdated.removeListener(chromeEvnet);
});
}
};
if (message.message === 'login') {
chrome.windows.create(
{
url:
'https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URL}&state=${state}',
type: 'popup',
},
() => {
chrome.tabs.onUpdated.addListener(chromeEvnet);
}
);
}
return true;
});