LoginSignup
13
10

More than 5 years have passed since last update.

webviewでGoogleのOAuth認証を行う

Last updated at Posted at 2016-11-30

概要

webviewを用いたGoogleのOAuth認証についての四苦八苦を記載します。後に述べますが、webviewからの従来の認証手順は使えなくなり、複雑なステップを踏む必要があります。冗長記述部分がありますので、結論が知りたい方は対応からご覧下さい。
Angularfire2を使用する手順を説明する日本語記事が少ないため、別途必要に応じ記載します。ここでは薄く触れます
なお、今回の前半に記載するweb用の設定は、Angular(2.0以降)でも流用可能な部分が多いです。

事前準備

以下のインストールなどを既に終えていることを前提とします。

  • Android SDKのインストール (Angularなら不要)
  • Android端末の用意またはavdシミュレータのインストール (Angularなら不要)
  • ionicと、cordovaまたはAngular(2.0以降)のインストール
  • firebaseプロジェクトの作成

環境構築

ionic2(またはwebアプリのみであればAngular(2.0以降))プロジェクトを作成し、AngularFire2をインストールします。

AngularFire2について

参考: https://github.com/angular/angularfire2

firebaseをAngularやionic2で使用するためのライブラリです。firebaseから取得したデータをObservableで取得したりします。

ionic2プロジェクト作成

以下コマンドでionic2プロジェクトを作成します。
既にプロジェクトがある場合不要です。

ionic start --v2 <プロジェクト名>
# angular cliの場合 ng new <プロジェクト名>
cd <プロジェクト名>

Angularfire2インストール

Angularfire2及びfirebaseライブラリを以下のコマンドでインストールします。
既にインストール済みの場合不要です。

npm install angularfire2 firebase --save

firebaseの設定

firebaseへのログインでGoogle OAuthを使用できる様に設定します。
既に設定済みの場合は不要です。

Google OAuthを使用可能にする

firebaseコンソールから、作成したfirebaseプロジェクトを選択します。
左ペインからAuthenticationを選択します

Authenticationが表示されます。ログイン方法タブを選択

プロバイダにログインの中から、Googleを選択し有効にするトグルをONにして、保存ボタンを押します

これでGoogle OAuthでfirebaseにログインできる様になったはずです。
尚、firebaseへのログインは、以下の方法をとることも可能です。
(試してません。今回はGoogleのみ説明します。)

  • メールアドレスとパスワード
  • Facebook
  • Twitter
  • GitHub
  • 匿名

apiKeyなどを取得する

firebaseのトップメニューからウェバプリにFirebaseを追加をクリックします。
(すでにアプリを追加している場合は、別のアプリを追加をクリックし、ウェブを選択します。)

ウェブアプリに Firebase を追加ウィンドウから、apiKey,authDomain, databaseURL, storageBucketを取得し、記録しておきます。すぐ使います。

コーディング(webアプリ向け)

Angularfire2を使用したfirebase,Googleの認証は以下の様なコードを記載します。

app.module.ts
import {AngularFireModule} from 'angularfire2';

~省略~
@NgModule({
  declarations: [
    ~省略~
  ],
   imports: [
    AngularFireModule.initializeApp(
      firebaseConfig,
      firebaseAuthConfig
    ),
  ],
  ~省略~


// 以下の値は、apiKeyなどの取得で取得した値。
export const firebaseConfig = {
  apiKey: 'APIキー',
  authDomain: 'ドメイン',
  databaseURL: 'URL',
  storageBucket: 'ストレージバケット'
};

// 以下の値は、認証設定。Google認証をリダイレクトで行う。
export const firebaseAuthConfig = {
  provider: AuthProviders.Google,
  method: AuthMethods.Redirect
};

import { AngularFire,
         FirebaseAuthState} from 'angularfire2';

@Component({
  templateUrl: 'テンプレート名.html'
})
export class Test{

  constructor(private af :AngularFire){}

  // ログインメソッド。templateのボタンクリックで呼び出される。
  login() :firebase.Promise<FirebaseAuthState>{
    return this.af.auth.login();
  }

}
template
<!-- ページにボタンを追加します。前後のコードは省きます。 -->
<button ion-button (click)="login()">Login</button>

コーディングはこんな感じです。

webアプリとして起動

以下のコマンドによりwebアプリケーションとして起動します。

ionic serve
# Angularの場合 ng serve

ページにボタンが表示されます。クリックするとログインすることができます。

Android用設定

web appとして作成したプロジェクトをAndroidのwebviewとして動作する様に対応します。

Androidプラットフォーム登録

ionicプロジェクトでAndroidを使用するには以下コマンドでAndroid用の設定を追加します。
(ios用設定は、mac環境であればデフォルトでインストールされます。)

ionic platform add android

起動(ログイン失敗)

Android端末をUSB接続し開発者オプション設定を行ったのち、アプリケーションのテストbuild及びインストールを行います

ionic run android --consolelogs --livereload --device
# avdで起動する場合、 --deviceは不要

これにより、apkの作成及びインストールが行われますがLOGINボタンを押しても、Androidブラウザが起動したり、全く反応がなかったり、とうまく動きません。

調査

Authメソッドには以下があります。

参考

  • Anonymous
  • CustomToken
  • OAuthToken
  • Password
  • Popup
  • Redirect

手っ取り早く試せるPopupも試しましたが動作しません。

やや脱線

facebookのOAuth認証にはcordovaプラグインが必要であるとの情報をいくつか見つけました

https://github.com/aaronksaunders/basicaf2
https://github.com/aaronksaunders/AngularFire2-Ionic2-Facebook
https://firebase.google.com/docs/reference/js/firebase.auth.FacebookAuthProvider#credential

Google認証についても調査してみます。
ng2-cordova-oauthというライブラリを発見しました。
https://github.com/nraboy/ng2-cordova-oauth

が、読み進めていくと・・・
https://github.com/nraboy/ng2-cordova-oauth#important-note-about-google
GoogleのOAuth認証は、webviewをブロックする旨の記事にぶちあたりました。ぎゃあす。

Google公式(英語):
Modernizing OAuth interactions in Native Apps for Better Usability and Security

Google公式(日本語):
ネイティブ アプリの OAuth インタラクションを最新にしてユーザビリティとセキュリティを向上する

要約すると、

  • webviewからのOAuth認証はセキュアじゃないがあるからブロック
  • 2016/10/20から段階的にブロック
  • 2017/04/20に原則ブロック
  • 代替手段は、
    • Google Sign-In
    • AppAuth

とのことでした。ぎゃあす。

参考:
OAuthの認証にWebViewを使うのはやめよう

対応

色々調べていくと、cordovaのプラグインcordova-plugin-googleplusを使用することで、webviewからOAuth認証を行うことが可能であることを確認しました。(まだ確認中の部分もありますが)

cordova-plugin-googleplus

プラグインの概要

  • iOSとAndroidで、Google Sign-inを使用してユーザ認証します。
  • email, display name, given name, family name, profile picture urlと user idを取得します。
  • Google Sign-In APIをラップしてるだけなので、ユースケースや開発に従い修正すべきだそうです。
  • Android向けとiOS向けのプロジェクトは同一にすることが強く推奨されています。
  • Androidの場合、(恐らく)端末のアカウントを使用するため、ログインという処理は不要の様です。

改修前の準備

Typescriptのプロジェクトディレクトリにある、config.xmlを開き、2行目くらいにある
パッケージidを確認します。このIDを後に使用します。

config.xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="ここです。" ...>
...
</widget>

iOSの対応

注意:iOSはテスト未実施です。誤りがある場合、別途修正します。

REVERSED_CLIEND_IDの取得

まず、REVERSED_CLIENT_ID(iOS URL Scheme)を取得します。(iOSのみ必要)
firebaseを使用する場合firebaseコンソールのfirebaseプロジェクトから登録を行います。
トップメニューからiOSアプリにFirebaseを追加を選択します。

ここのiOSバンドルIDに、先ほど取得したパッケージidを指定しアプリを追加すると、自動的にダウンロードされるGoogleService-Info.plistに、REVERSED_CLIENT_IDの記載があります。これを記録します。

GoogleService-Info.plist
<key>REVERSED_CLIENT_ID</key>
<string>ここです</string>

Androidの対応

iOSと同様にfirebaseコンソールから登録を行います。

OAuthクライアントIDの取得

トップメニューからAndroidアプリにFirebaseを追加を選択します。

ここのパッケージ名に、先ほど取得したパッケージidを指定しアプリを追加をすると、自動的にダウンロードされる、google-services.jsonに、REVERSED_CLIENT_IDの記載があります。これを記録します。

google-services.json
      "oauth_client": [
        {
          "client_id": "ここです",
          "client_type": 3
        }

クライアント認証キーの取得

参考
keytoolを使用して、クライアント認証用のハッシュ値(SHA-1)を取得します。

keytool -exportcert -list -v \
-alias androiddebugkey -keystore ~/.android/debug.keystore

デバッグ用パスワードのデフォルトはandroidです。これにより以下の様に認証キーを取得できます。

SHA1: 〜〜〜〜ハッシュ値〜〜〜〜

認証キーの登録

再び、firebaseコンソールに戻り、トップメニューのAndroidから管理をクリックし、

フィンガープリントを追加ボタンから、取得した認証キーを登録します。

cordovaプラグイン登録

漸くプラグインの登録を行います。以下のコマンドをTypescriptのプロジェクトディレクトリで実行します。

# npmから取得する場合
cordova plugin add cordova-plugin-googleplus --save --variable REVERSED_CLIENT_ID=ここにiOSの手順で取得したIDを入れる

# githubから最新を取得する場合
cordova plugin add https://github.com/EddyVerbruggen/cordova-plugin-googleplus --save --variable REVERSED_CLIENT_ID=ここにiOSの手順で取得したIDを入れる

cordova prepare

ログインメソッドの修正

参考:
https://forum.ionicframework.com/t/how-to-add-an-ionic-2-google-login/51114/10

先述の通り、Androidのwebview上でも既にGoogleのOAuthにログインしている状態ですが、ログインボタン押下で認証情報をダイアログに表示するように改修してみます。

 login(){
     window['plugins'].googleplus.login(
         {
           // 'scopes': '',
           'webClientId': 'ここにAndroidの手順で取得したgoogle-services.jsonのclient-idを入れる',
           'offline': false,
         },
         function (authData) {
           alert(JSON.stringify(authData)); // do something useful instead of alerting
         },
         function (msg) {
           alert('error: ' + msg);
         }
     );
   }

アプリの起動

再び以下のコマンドでアプリを起動します。

ionic run android --consolelogs --livereload --device

ログインボタンを押した時に認証情報をアラート表示できれば、まずはGoogle OAuthの認証に成功しました。

firebaseへのログイン

Google OAuthでログインした情報を使用し、firebaseへのログインを試みます。
認証データのidTokenを用い、GoogleAuthProvidercredentialメソッドを呼び出し、firebase.auth.AuthCredentialを取得します。
このcredentialを用いて、signInWithCredentialメソッドによりサインインを行います。

これをngOnInitメソッドで使ってみます

  ngOnInit(){
    window['plugins'].googleplus.login(

        {
           // 'scopes': '',
           'webClientId': 'ここにAndroidの手順で取得したgoogle-services.jsonのclient-idを入れる',
           'offline': false,
        },
        function (authData) {

          let credential = (<any>firebase.auth.GoogleAuthProvider).credential(authData.idToken);
          firebase.auth().signInWithCredential(credential);

        },
        function (msg){
          console.log('acquireAuth error: ' + msg);
        }
    );
  }

この処理により、ログインができました。
ログインの確認は、コンストラクタで定義しているAngularfireサービスを用いてthis.af.authで認証を取得できます。

2016/12/26追記:

書き忘れましたすみません :P
このプラグイン「cordova-plugin-googleplus」は、cordova CLIで起動する必要があります。(ionic cliではうまく動きません。)
以下のようにcordova cliから起動することはできますが、このコマンドではコンソール(ターミナル)にログが出力できません。

cordova run android --device

そのため、テストには不向きです。OSに従い、以下の手順を実施してください。

Android

コンソールへのログ出力を行うためには Android SDKを使用します。
Android SDKのインストール方法は、cordovaの以下を参照願います。
https://cordova.apache.org/docs/ja/latest/guide/platforms/android/

Android SDKを開いたら、右ペインから「Import project (Eclipse ADT, Gradle, etc.)」を選択し、
image

{プロジェクトディレクトリ}/platforms/androidを指定し、Debugで起動してください。
Android SDK上にログが表示されます。

ios

{プロジェクトディレクトリ}/platforms/ios/{プロジェクト名}.xcodeproj
を実行し、xcode上からrunしてください。(未実施)

13
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
10