概要
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
のみ説明します。)
- メールアドレスとパスワード
- GitHub
- 匿名
apiKeyなどを取得する
firebaseのトップメニューからウェバプリにFirebaseを追加
をクリックします。
(すでにアプリを追加している場合は、別のアプリを追加
をクリックし、ウェブ
を選択します。)
ウェブアプリに Firebase を追加
ウィンドウから、apiKey
,authDomain
, databaseURL
, storageBucket
を取得し、記録しておきます。すぐ使います。
コーディング(webアプリ向け)
Angularfire2を使用したfirebase,Googleの認証は以下の様なコードを記載します。
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();
}
}
<!-- ページにボタンを追加します。前後のコードは省きます。 -->
<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
とのことでした。ぎゃあす。
対応
色々調べていくと、cordovaのプラグインcordova-plugin-googleplus
を使用することで、webviewからOAuth認証を行うことが可能であることを確認しました。(まだ確認中の部分もありますが)
プラグインの概要
- 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を後に使用します。
<?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
の記載があります。これを記録します。
<key>REVERSED_CLIENT_ID</key>
<string>ここです</string>
Androidの対応
iOSと同様にfirebaseコンソールから登録を行います。
OAuthクライアントIDの取得
トップメニューからAndroidアプリにFirebaseを追加
を選択します。
ここのパッケージ名に、先ほど取得したパッケージid
を指定しアプリを追加
をすると、自動的にダウンロードされる、google-services.json
に、REVERSED_CLIENT_ID
の記載があります。これを記録します。
"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を用い、GoogleAuthProvider
のcredentialメソッドを呼び出し、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.)」を選択し、
{プロジェクトディレクトリ}/platforms/android
を指定し、Debugで起動してください。
Android SDK上にログが表示されます。
ios
{プロジェクトディレクトリ}/platforms/ios/{プロジェクト名}.xcodeproj
を実行し、xcode上からrunしてください。(未実施)