前回はExpo CLIでReact Nativeプロジェクトを作成しました。今回は同じくExpoを使って、Google OAuth認証を実装するネイティブアプリをReact Nativeで実装してみます。
OAuthとは
OAuth、特に2.0については下記の記事参照。
今回作成するアプリは上記記事例のクライアントに相当し、Google API バックエンドがリソースサーバ・認可サーバを兼任します(内部で別れているのかもしれませんが)。リソースオーナーはクライアントIDなど、APIリクエストに必要な情報を発行します。
ExpoアプリでGoogle OAuth認証を実装する
それでは早速作っていきましょう。
なおクライアント端末はiOSの前提で進めています。
リソースオーナー(Googleアカウント)側の設定
アカウントの作成
実装に入る前に、Google OAuth に利用する開発者用アカウントを用意します。
Googleアカウントを持っていない方はアカウントを作成してください。
GCPプロジェクトの作成
アカウントを作成したら、GCP内にアプリ専用のプロジェクトを作成します。このプロジェクト単位に認証情報や使用ライブラリを管理できます。
まず、Google Developer Credentialsにアクセスします。
ロゴ右隣のプロジェクト名欄をクリック。
プロジェクト選択ダイアログが表示されるので、「新しいプロジェクト」をクリック。
プロジェクト作成フォームが表示されます。プロジェクト名を入力し、「作成」ボタンをクリック。
これでアプリプロジェクトがGoogle API Console上に作成されました。
iOSクライアントIDを作成
次に、OAuth APIに必要なクライアントIDを作成していきます。
Google Developer Credentialsの「認証情報」タブの画面中央の「認証情報の作成」をクリックします。
クリックするといくつかの選択肢が出るので、「OAuth クライアント キー」をクリック。
キーの作成画面に遷移します。Google APIを呼び出すアプリケーションの種類について聞かれるので、クライアント端末の機種がiOSの場合は「iOS」を、Androidの場合は「Android」を選択します。
ラジオボタンの一つを選択すると、詳細設定のための入力欄が表示されます。クライアントIDの名前と、バンドルIDを入力します。バンドルIDはアプリケーションを一意に識別する名前のため、一意になるような名前を設定します(com.hoge.fuga.piyoなど)。
今回はExpoアプリで実行するため、 host.exp.exponent
と設定します。(バンドルIDがこれと異なると、Expoアプリ上でGoogle OAuthができません)
※参考
入力を確定すると、クライアントIDが発行されます。 このクライアントIDは後ほどExpoアプリ内で使用します。
クライアントアプリの実装
いよいよ実装に入ります。
プロジェクトの作成
その前にアプリケーションの開発環境を作成しなければいけません。なので下記記事に従い、Expo CLIでReact Nativeプロジェクトを作成していきます。
app.json
の設定
次に、クライアント端末側の app.json
にプロパティを追加します。
app.json
のJSONに ios
プロパティを追加し、その直下に bundleIdentifier
config.googleSignin.reservedClientId
を追加してください。bundleIdentifier
は host.exp.exponent
に、 reservedClientId
はiOSクライアントIDを逆にしたものを設定してください。
{ ... "ios": { "bundleIdentifier": "host.exp.exponent", "config": { "googleSignIn": { "reservedClientId": "{iOSクライアントIDを逆にしたもの : com.hoge.fugaだったらfuga.hoge.com}" } } } } }
App.js
フロントビューと、ビューロジックの実装になります。
画面には認証用のボタンをひとつ配置しており、そのボタンを押すことでGoogleのOAuth認証が起動するようになっています。OAuthの起動は expo.Google.logInAsync
によって行われます。
import React from 'react'; import { StyleSheet, Text, View, Button } from 'react-native'; import expo from 'expo'; export default class App extends React.Component { render() { return ( <View style={styles.container}> <Button onPress={this.signInWithGoogle} title="Sign in with Google" /> </View> ); } // Google OAuth認証メソッド async signInWithGoogle() { try { const result = await expo.Google.logInAsync({ behavior: 'web', iosClientId: '{iOSクライアントID}', scopes: ['profile', 'email'], }); // 認証に成功したら、アクセストークンが標準出力される if (result.type === 'success') { console.log('Google Access Token: ' + result.accessToken); } } catch (e) { console.log(e); } } } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, });
今回はブラウザアプリを開く形でGoogle OAuth認証画面を表示しています。 認証に成功すると、コンソール上に認可アクセストークンが表示されます。このアクセストークンを第三者が使用することで、限定された範囲で認証ユーザの情報にアクセスできるようになります。
これでアプリ起動の準備が整いました!
Demo
実際にアプリを起動して、挙動を確かめてみます。
npm run start
を実行し、起動時に開いたブラウザ画面、またはコンソール上のQRコードを端末でスキャンし、アプリをインストールします(Expo Clientアプリが必要です)。
詳しいローカル起動方法は下記記事を参照。
起動が成功すると、下記のような画面が表示されます。「Sign in with Google」ボタンを押すと、OAuth認証の画面へ遷移します。
iOSの場合、Expoアプリがgoogle.comをブラウザ開くことを許可するかどうか確認するダイアログが表示されるので「続ける」をクリック。
Googleログインが未実行の場合、Googleアカウントのメールアドレスとパスワードを聞かれます。所有するGoogleアカウントのメールアドレス・パスワードを入力し、ログインを実行してください。
ログインが成功すると、もとのアプリ画面に戻ります。コンソール上にアクセストークンが表示されれば、認証成功です。
余談
Expoの expo.Google.loginAsync
ではスタンドアロンアプリとしての認証オプションも用意してあるのですが、端末のOSごとに細かい設定が必要みたいなので今回は behavior = web
を使用しての実装を採用しました。
参考文献
OAuth 2.0 for Mobile & Desktop Apps | Google Identity Platform | Google Developers