class: center, middle # Expo と Firebase Authentication We Are JavaScripters! @30th
2019-03-22
okamuuu --- class: center, middle # こんにちは --- ## Expo と Firebase Authentication のお話です Firebase Authentication を React Native で実装しようとすると大変だったのでそこで得た知見を共有しつつ、
もっといい解決策があればご教授頂きたい
です。 --- ## あらすじ * 少人数の開発チームでプロダクトをつくりたいので Expo を使いたい * Facebook, Google, Github, Twitter でログインする処理が必要 * Expo + Firebase Authentication を使えば簡単...? --- ## 実は意外と大変だった * React Native は JavaScript だけどブラウザ上で動くわけでは無い * Firebase SDK に丸ごとお任せしたかったが
そういうわけにはいかなかった
* OAuth の事を思い出す必要があった * サーバーサイドでの実装が必要になった --- ## 特に伝えたいこと *
React Native
と
Firebase
と
OAuth
と
サーバーサイド
の知識が必要になる * 何も知らずに導入しようとすると
意外とコストがかかります
* そのあたりを Expo + Firebase Authentication を考えている人たちは参考にしてください * すでに使っている人たちでもっといい方法あったら
是非教えてください
--- class: center, middle # 本題 --- class: center, middle ## React Native と Firebase Authentication を選んだ理由 --- ## 少人数の開発チームでプロダクトをつくりたい * Expo を使いたい *
クロスプラットフォーム
で開発ができる * Xcode に触らなくても app-store に申請手続を行う事ができる * メンテナンスが
属人化
されるのを防げる予感 --- ## 認証処理の実装は思った以上に手間がかかる * 仮会員登録、メール認証、本会員登録の処理は面倒臭い * OAuth 面倒臭い * ユーザーが端末を紛失した場合にどうやってログアウトさせるのか * ちゃんとしようとすると意外と面倒くさいことに気付き始める * これらの実装をハンドリングする自信ない * Firebase Authentication に
お任せしたい
--- class: center, middle # WEB の場合は簡単だった --- ## WEB + Firebase Authentication SDK を使えば認証処理を全て委ねることができた ```javascript // event を設定する firebase.auth().onAuthStateChanged(user => { ... }) // ログインする var provider = new firebase.auth.GoogleAuthProvider(); firebase.auth().signInWithPopup(provider) // ログアウトする firebase.auth().signOut() ``` --- class: center, middle # React Native の場合 --- ## React Native + Firebase Authentication * `signInWithPopup` も `signInWithRedirect` もつかえない * 代わりに `signInWithCredential` を使う事になる ```javascript var credential = getCredential() // ここを自分で実装する必要がある firebase.auth().signInAndRetrieveDataWithCredential(credential); ``` credential をつくるには各プロバイダーの
access token
を取得する必要がある。 --- ## 各プロバイダーのAccess Token を取得するには? * Facebook に関しては Expo が良きにはからってくれる * Google と Github は OAuth 2.0 * Twitter は OAuth 1.0 というわけで実際に実装が必要だったのは Google, Github, Twitter --- class: center, middle ## access token の前に OAuth についておさらい --- ## OAuth のおさらい access token についてお話しする前に OAuth 2.0 と OAuth 1.0 の違いについてあやふやな人が多いと思います。 --- ## OAuth 2.0 と OAuth 1.0 の違い * OAuth 2.0
チョット
メンドクサイ * OAuth 1.0
モット
メンドクサイ 注: 個人の見解です --- ## OAuth 2.0 と OAuth 1.0 の違い 1.0 には以下の問題点があります * 過度な認証フローと複雑な署名 * モバイルアプリへの対応 * スケール時のパフォーマンス 以下の URL に詳しい記事を書いてくれている人がいますので
ご安心ください。
https://murashun.jp/blog/20150920-01.html --- class: center, middle ## 閑話休題 access token を取得する必要がある、という話題に戻ります --- ## Facebook(Expo) Facebook に関しては Expo が良きにはからってくれる ```javascript import { AuthSession, Facebook } from 'Expo' async handleFacebookLogin() { const { type, token } = await Facebook.logInWithReadPermissionsAsync( FACEBOOK_APP_ID, { permissions: ['public_profile'] } ) if (type !== 'success') { return } const credential = firebase.auth.FacebookAuthProvider.credential(token) firebase.auth().signInAndRetrieveDataWithCredential(credential) } ``` --- ## Google(Expo) ```javascript const REDIRECT_URL = AuthSession.getRedirectUrl() async handleGoogleLogin() { // 認可コードを取得する。Expo が手助けしてくれる const result = await AuthSession.startAsync({ authUrl: `https://accounts.google.com/o/oauth2/v2/auth?` + `&client_id=${GOOGLE_CLIENT_ID}` + `&redirect_uri=${REDIRECT_URL}` + `&response_type=code` + `&access_type=offline` + `&scope=profile`, }); // 認可コードをアクセストークンに交換する。自分で実装する必要がある const { id_token } = await createTokenWithCode('google', result.params.code) var credential = firebase.auth.GoogleAuthProvider.credential(id_token); firebase.auth().signInAndRetrieveDataWithCredential(credential); } ``` --- ## Google(Node.js) ```javascript app.post('/auth/google', async (req, res) => { const { code, redirect_uri } = req.body // 認可コードを access token と交換する処理は秘密鍵が必要 async function createTokenWithGoogleCode(code, redirect_uri) { const url = `https://www.googleapis.com/oauth2/v4/token` const res = await fetch(url, { method: 'POST', body: JSON.stringify({ code, client_id: config.GOOGLE.CLIENT_ID, client_secret: config.GOOGLE.CLIENT_SECRET, redirect_uri, grant_type: 'authorization_code' }) }); return await res.json() } return res.json(await createTokenWithGoogleCode(code, redirect_uri)) ``` --- class: center, middle ## Github, Twitter に関しては割愛します Qiita にソースコードを載せてあります。 --- # まとめ Expo で Firebase Authentication を実装しようとすると
React Native
と
Firebase
と
サーバーサイドで OAuth の認証処理
を実装できるエンジニアが必要です --- # まとめ 当事者になってしまった人場合は以下の記事を参考にして何とか乗り切ってください。 https://qiita.com/okamuuu/items/6da12f295c3b8a7bc3d8 --- class: center, middle ## 私にお金払う方法もあります。 --- class: center, middle ## ご静聴ありがとうございました