Firebase OAuth workflow
Firebase OAuth custom provider workflow
Firebase에 트위치 OAuth로 인증 기능을 사용할 때 처음에 이해가 안가는 부분이 있어서 헤메다가 왜 헤맸는지를 Firebase의 OAuth workflow를 설명하면서 정리하고자 한다.
Firebase OAuth workflow
사용자 조작으로 signInWithPopup()을 호출하면
1. Firebase API로 사용자에게 보여줄 OAuth uri 요청
POST www.googleapis.com/identitytoolkit/v3/relyingparty/createAuthUri?key={firebaseConfig.apiKey}
{
"continueUri": "https://wrd-user-filter.firebaseapp.com/__/auth/handler",
"customParameter": {},
"oauthScope": "{\"google.com\":\"profile\"}",
"providerId": "google.com"
}
200
{
"authUri": "https://accounts.google.com/o/oauth2/auth?response_type=code&client_id={google.client_id(auto)}&redirect_uri=https://wrd-user-filter.firebaseapp.com/__/auth/handler&state={state_code}&scope={scope}",
"kind": "identitytoolkit#CreateAuthUriResponse",
"providerId": "google.com",
"sessionId": "{sessionId}"
}
GET https://accounts.google.com/o/oauth2/auth?response_type=code&client_id={google.client_id(auto)}&redirect_uri={authUri}&context_uri={context_uri}
302 https://accounts.google.com/o/oauth2/auth?response_type=code&client_id={google.client_id(auto)}&redirect_uri={authUri}&context_uri={context_uri}
GET {authUri} = https://wrd-user-filter.firebaseapp.com/__/auth/handler?state={state_code}&code={auth_code}&scope={scope}&authuser=0&prompt=none
POST https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyAssertion?key=AIzaSyBA9iVpvQJLSaOywTzMUiBung4-GFKuJ9Q
{
"requestUri": "https://wrd-user-filter.firebaseapp.com/__/auth/handler?state={state_code}&code={auth_code}&scope={scope}&authuser=0&prompt=none",
"returnIdpCredential": true,
"returnSecureToken": true,
"sessionId": "{sessionId}"
}
200
{
"context": "",
"displayName": "{displayName}",
"email": "{email}",
"emailVerified": true,
"expiresIn": "3600",
"federatedId": "https://accounts.google.com/{federatedId}",
"firstName": "{firstName}",
"fullName": "{fullName}",
"idToken": "{idToken}",
"kind": "identitytoolkit#VerifyAssertionResponse",
"lastName": "{lastName}",
"localId": "{localId}",
"oauthAccessToken": "{oauthAccessToken}",
"oauthExpireIn": 3598,
"oauthIdToken": "{oauthIdToken}",
"photoUrl": "{photoUrl}",
"providerId": "google.com",
"rawUserInfo": "{rawUserInfo}"
}
이와 같이 Firebase에서 기본적으로 제공해주는 OAuth 프로바이더는 프론트엔드, 백엔드에서 OAuth를 위해 별도의 과정을 수행할 필요가 없다.
Firebase OAuth custom provider workflow
Firebase에서 지원하지 않는 커스텀 프로바이더를 사용할 때는 Firebase OAuth workflow 5의 과정을 수행할 백엔드가 어떠한 형태든 필요하다.
일반적인 OAuth과정 처럼 토큰을 받아온 후
1. 백엔드에 토큰을 전달한다. (개발자마다 구현이 다른 부분)
GET http://localhost:5000/implicit?access_token={access_token}
const firebaseToken = await admin.auth().createCustomToken(twitchUser.id);
200 JSONP
"{idToken}"
this.afAuth.signInWithCustomToken(idToken);
POST http://localhost:9099/identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken?key=AIzaSyB0EeQFiKVkUyq_zpY8UPJMUv-JZUklpX4
{
"token":"{idToken}",
"returnSecureToken":true
}
200
{
expiresIn: "3600"
idToken: "{secureIdToken}"
isNewUser: false
kind: "identitytoolkit#VerifyCustomTokenResponse"
refreshToken: "{refreshIdToken}"
}
signInWithCustomToken에 사용할 토큰을 만드는 별도의 서버가 필요하다.
Firebase의 기본 Auth 기능만 사용하다가 커스텀 프로바이더가 필요해서 자바스크립트에서 커스텀 인증 시스템을 사용하여 Firebase에 인증 설명을 봤을 때 별도의 서버가 필요하다는 것을 한번에 이해하기 힘들었다.
사용자가 앱에 로그인하면 사용자의 로그인 인증 정보(예: 사용자 이름과 비밀번호)를 인증 서버로 전송하세요. 서버가 사용자 인증 정보를 확인하여 정보가 유효하면 커스텀 토큰을 반환합니다.
원문
이 인증 서버가 별도의 서버라는 것을 이해하는데 많은 시행착오가....
Firebase API 문서를 볼 때 admin 관련된 무언가가 있으면 이는 백엔드에서 수행하는 일이란 뜻이다.