Works by

Ren's blog

アプリケーションバックエンド中心に書いていきます

【ReactNative/Expo】Google OAuth認証をReact Native(Expo)アプリに実装する

f:id:rennnosukesann:20190101154829p:plain:w300

前回はExpo CLIでReact Nativeプロジェクトを作成しました。今回は同じくExpoを使って、Google OAuth認証を実装するネイティブアプリをReact Nativeで実装してみます。

OAuthとは

OAuth、特に2.0については下記の記事参照。

rennnosukesann.hatenablog.com

今回作成するアプリは上記記事例のクライアントに相当し、Google API バックエンドがリソースサーバ・認可サーバを兼任します(内部で別れているのかもしれませんが)。リソースオーナーはクライアントIDなど、APIリクエストに必要な情報を発行します。

ExpoアプリでGoogle OAuth認証を実装する

それでは早速作っていきましょう。

なおクライアント端末はiOSの前提で進めています。

リソースオーナー(Googleアカウント)側の設定

アカウントの作成

実装に入る前に、Google OAuth に利用する開発者用アカウントを用意します。

Googleアカウントを持っていない方はアカウントを作成してください。

ログイン - Google アカウント

GCPプロジェクトの作成

アカウントを作成したら、GCP内にアプリ専用のプロジェクトを作成します。このプロジェクト単位に認証情報や使用ライブラリを管理できます。

まず、Google Developer Credentialsにアクセスします。

console.developers.google.com

ロゴ右隣のプロジェクト名欄をクリック。

f:id:rennnosukesann:20190101165923p:plain

プロジェクト選択ダイアログが表示されるので、「新しいプロジェクト」をクリック。

f:id:rennnosukesann:20190101170026p:plain

プロジェクト作成フォームが表示されます。プロジェクト名を入力し、「作成」ボタンをクリック。

f:id:rennnosukesann:20190102130355p:plain

これでアプリプロジェクトがGoogle API Console上に作成されました。

iOSクライアントIDを作成

次に、OAuth APIに必要なクライアントIDを作成していきます。

Google Developer Credentialsの「認証情報」タブの画面中央の「認証情報の作成」をクリックします。

f:id:rennnosukesann:20190101160444p:plain

クリックするといくつかの選択肢が出るので、「OAuth クライアント キー」をクリック。

f:id:rennnosukesann:20190101161850p:plain

キーの作成画面に遷移します。Google APIを呼び出すアプリケーションの種類について聞かれるので、クライアント端末の機種がiOSの場合は「iOS」を、Androidの場合は「Android」を選択します。

f:id:rennnosukesann:20190101161935p:plain

ラジオボタンの一つを選択すると、詳細設定のための入力欄が表示されます。クライアントIDの名前と、バンドルIDを入力します。バンドルIDはアプリケーションを一意に識別する名前のため、一意になるような名前を設定します(com.hoge.fuga.piyoなど)。

今回はExpoアプリで実行するため、 host.exp.exponent と設定します。(バンドルIDがこれと異なると、Expoアプリ上でGoogle OAuthができません)

※参考

github.com

f:id:rennnosukesann:20190101162550p:plain

入力を確定すると、クライアントIDが発行されます。 このクライアントIDは後ほどExpoアプリ内で使用します。

f:id:rennnosukesann:20190101163120p:plain

クライアントアプリの実装

いよいよ実装に入ります。

プロジェクトの作成

その前にアプリケーションの開発環境を作成しなければいけません。なので下記記事に従い、Expo CLIでReact Nativeプロジェクトを作成していきます。

rennnosukesann.hatenablog.com

app.json の設定

次に、クライアント端末側の app.json にプロパティを追加します。 app.jsonJSONios プロパティを追加し、その直下に bundleIdentifier config.googleSignin.reservedClientId を追加してください。bundleIdentifierhost.exp.exponent に、 reservedClientIdiOSクライアントIDを逆にしたものを設定してください。

{
...
    "ios": {
      "bundleIdentifier": "host.exp.exponent",
      "config": {
        "googleSignIn": {
          "reservedClientId": "{iOSクライアントIDを逆にしたもの : com.hoge.fugaだったらfuga.hoge.com}"
        }
      }
    }
  }

}

App.js

フロントビューと、ビューロジックの実装になります。 画面には認証用のボタンをひとつ配置しており、そのボタンを押すことでGoogleOAuth認証が起動するようになっています。OAuthの起動は expo.Google.logInAsync によって行われます。

Google - Expo Documentation

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アプリが必要です)。

詳しいローカル起動方法は下記記事を参照。

rennnosukesann.hatenablog.com

起動が成功すると、下記のような画面が表示されます。「Sign in with Google」ボタンを押すと、OAuth認証の画面へ遷移します。

f:id:rennnosukesann:20190102130012p:plain:w300

iOSの場合、Expoアプリがgoogle.comをブラウザ開くことを許可するかどうか確認するダイアログが表示されるので「続ける」をクリック。

f:id:rennnosukesann:20190102130123p:plain:w300

Googleログインが未実行の場合、Googleアカウントのメールアドレスとパスワードを聞かれます。所有するGoogleアカウントのメールアドレス・パスワードを入力し、ログインを実行してください。

f:id:rennnosukesann:20190102130236p:plain:w300

ログインが成功すると、もとのアプリ画面に戻ります。コンソール上にアクセストークンが表示されれば、認証成功です。

f:id:rennnosukesann:20190102131905p:plain

余談

Expoの expo.Google.loginAsync ではスタンドアロンアプリとしての認証オプションも用意してあるのですが、端末のOSごとに細かい設定が必要みたいなので今回は behavior = webを使用しての実装を採用しました。

github.com

参考文献

Google - Expo Documentation

OAuth 2.0 for Mobile & Desktop Apps  |  Google Identity Platform  |  Google Developers