Open13
firebase auth関連
サーバーでの認証のハンドリング
golang twitter
jsonのサンプルでfirebase以下の部分は型が map[string]interface{}
なので、データの整形がgoだと少し面倒
tsとかのほうが書きやすそう・・・
type (
Claims struct {
Name string
Picture string
TwitterID string
}
FirebaseAuth struct {
*auth.Token
Claims
}
)
func abstractSlice(arr interface{}) []string {
var dest []string
switch sl := arr.(type) {
case []interface{}:
for _, b := range sl {
dest = append(dest, fmt.Sprint(b))
}
case []string:
for _, str := range sl {
dest = append(dest, str)
}
case []int:
for _, i := range sl {
dest = append(dest, fmt.Sprint(i))
}
}
return dest
}
func DecodeToken(token string) (*FirebaseAuth, error) {
auth, err := newFirebase()
if err != nil {
return nil, errors.Wrap(err, "failed to create firebase client")
}
ctx := context.Background()
verifyToken, err := auth.VerifyIDToken(ctx, token)
if err != nil {
return nil, errors.Wrap(err, "failed to verify token")
}
if verifyToken == nil {
return nil, errors.New("token is nil")
}
// json example:
//{
// "name": "Kobayashi.Yasushi",
// "picture": "https://pbs.twimg.com/profile_images/869211171517120512/bhVNCS-m_normal.jpg",
// "iss": "https://securetoken.google.com/twitter-hogehoge",
// "aud": "twitter-hogehoge",
// "auth_time": 1651825626,
// // uid
// "user_id": "uid",
// "sub": "",
// "iat": 1651825626,
// "exp": 1651829226,
// "firebase": {
// "identities": {
// "twitter.com": [
// "0101010101"
// ]
// },
// "sign_in_provider": "twitter.com"
// }
// }
name, _ := verifyToken.Claims["name"]
profileImage, _ := verifyToken.Claims["picture"]
fire, _ := verifyToken.Claims["firebase"]
// nolint:forcetypeassert
castFire := fire.(map[string]interface{})
identities, _ := castFire["identities"]
// nolint:forcetypeassert
castIdentities := identities.(map[string]interface{})
twitter := abstractSlice(castIdentities["twitter.com"])
// nolint:forcetypeassert
res := &FirebaseAuth{
Token: verifyToken,
Claims: Claims{
Name: name.(string),
Picture: profileImage.(string),
TwitterID: twitter[0],
},
}
return res, nil
}
auth0との機能面での比較
パスワードポリシー
- auth0は簡単に管理画面で設定可能
- firebaseには現状の機能としてなさそうなので、完全にパスワードポリシーを準拠するためには、サーバー側からユーザー作成等が必要そう
- rate limitはデフォルトで設定されており、簡単に変更可能
認証方法の柔軟性
- firebaseはカスタム認証の自由度が高そう?
- auth0はpipelineで色々柔軟にできる(指定企業だけMFAを必須にする等)し、そもそも多機能なので、ぱっと思いつくことは大体できた
料金は、firebaseの方が圧倒的に安いが、基本的なことはどちらもほぼ無料でできる
フロント
onAuthStateChanged
というメソッドがあり、firebaseの認証状況変化に合わせて、色々な処理を簡単にかけるのがめちゃくちゃ楽
nextなら、これを_app.tsxに入れておけば簡単に認証制御できる
docker/firebase emulatorでローカル環境構築
公式のfirebase emulatorのイメージはないが、firebase cliにデフォルトでemulatorの機能が入っていいるので、それを使える
一つのプロジェクトであれば、普通に起動して使えるが、複数のプロジェクトのfirebase authを構築したい場合はfirebase emulatorもgolangのclientも対応不十分
emulatorなのでと割り切って、一つのプロジェクトでやるのが良さそう
--export-on-exit
というオプションはあるが、dockerが止まっても動くものではないので、データの永続化ができない