はじめに
Angular な SPA(Single Page Applicaiton)で、Facebook の OAuth 認証を実現する方法のご紹介です。
始めは以下の記事と同じように、angular-oauth2-oidc
というライブラリを使用して実現しようとしたのですがうまくできませんでした。
このライブラリは、XMLHttpRequest で OAuth 認証サーバーにアクセスするのですが、Facebook だとアクセスポイントと思われる URL にリクエストを投げると、CORS(Cross-Origin Resource Sharing)のエラーが発生してしまうのですよね。
しかし、Angular のngx-facebook
というライブラリが見つかり、これを使えばなんとかできることが分かりました。
なお、動作確認は以下の環境で行っています。
- Windows 10
- Visual Studio Code
- Angular: 7.0.0
Facebook での設定
Facebook for Developers にアクセスしてアプリを登録します。
なお、このサイトは頻繁に UI が変わるようなので概要だけ記述します。
まず、「マイアプリ」から「新しいアプリの追加」をクリックします。
表示される画面で、「表示名」「連絡先メールアドレス」を入力し、アプリ ID を作成します。
セキュリティチェックの画面が表示されるので、チェックを入れて先に進みます。
ダッシュボードが表示されるので、「Facebook ログイン」の「設定」をクリックします。
クイックスタートで「ウェブ」をクリックします。
ウェブサイトの URL は Angular を使用するので、今回はhttps://localhost:4200
を指定します。
画面左メニューの、設定>ベーシックより、アプリの設定を行います。アプリを公開するために「プライバシーポリシーのURL」と「利用規約のURL」を入力し保存します(有効なURLであること)。
画面左メニューの、プロダクト>Facebook ログイン>設定より、OAuth の設定を行います。
「クライアントOAuthログイン」「ウェブ OAuth ログイン」と「埋め込みブラウザーOAuthログイン」を「はい」にして、「有効なOAuthリダイレクトURI」を入力し設定を保存します。
なお、リダイレクト URI は HTTPS である必要があります。
macOS で Angular を HTTPS化する方法は下記記事を参考にしてください。
画面左メニューの、アプリレビューよりアプリを公開にします。
これを行わないと、通常のユーザーでの動作確認ができません。
以上で、Facebook の設定は終了になります。
Angular プロジェクトの設定
Angular のプロジェクトのルートフォルダで、ngx-facebook
をインストールします。
$ npm i --save ngx-facebook
index.html
に以下の行を追加します。
<script type="text/javascript" src="https://connect.facebook.net/en_US/sdk.js"></script>
app.module.ts
に以下の設定を追加します。
import { FacebookModule } from 'ngx-facebook'; //追加 @NgModule({ ... imports: [ FacebookModule.forRoot() //追加 ], ... }) export class AppModule { }
Facebook のログインを行う画面のコンポーネント、またはサービスに以下の設定を追加します。
ログイン、ログイン状態確認、ログオフの実装も記述しています。
なお、ログオフについては、ドキュメント通り行っているのですが、正常にログオフできませんでした。これは、アプリケーションのログオフ時に、Facebook までログオフする必要があるかと考えると不要だと思うので、実際には問題にならないと思います。
import { FacebookService, InitParams } from 'ngx-facebook'; export class MyComponentOrService { constructor(private fb: FacebookService) { let initParams: InitParams = { appId: 'アプリID', cookie: true, xfbml: true, version: 'v3.1' }; fb.init(initParams); } // ログイン処理 loginWithFacebook(): void { let options: LoginOptions = { enable_profile_selector: true, return_scopes: true, scope: 'public_profile,email' // 公開プロフィールとメールアドレスにアクセス }; this.fb.login(options) .then((response: LoginResponse) => { console.log('login success!'); // アクセストークン console.log('access token:' + response.authResponse.accessToken); this.fb.api('/me?fields=id,email,name') .then((_response: any) => { // 氏名 console.log('Name:' + _response.name); // メールアドレス console.log('email:' + _response.email); // ユーザー ID console.log('id:' + _response.id); // 小さなプロフィール画像ダウンロードURL console.log('picture 50px:' + '//graph.facebook.com/' + _response.id + '/picture'); // 大きなプロフィール画像ダウンロードURL console.log('picture 200px:' + '//graph.facebook.com/' + _response.id + '/picture?type=large'); }).catch((reason) => console.log(reason)); }).catch((error: any) => console.error(error)); } // ログイン状態確認 checkLoginStatus(): void { this.fb.getLoginStatus() .then((response) => { if (response.status === 'connected') { console.log('login now.'); } else { console.log('logout now.'); } }).catch((reason) => console.log(reason)); } // ログオフ処理(注:現在はエラーで動作しない) logoutWithFacebook(): void { this.fb.logout() .then(() => { console.log('logouted.'); }).catch((reason) => console.log(reason)); } }
動作確認
下記コマンドを実行して、HTTPS で Angular の Web サーバーを起動します。
$ ng serve --ssl
おわりに
ライブラリを使用することにより、比較的簡単に Facebook で OAuth 認証を行うことができました。
実際には、JavaScript の Facebook SDK を使用しようとして、かなり苦労した上で断念しているのですけどね。💦
まあ、よいライブラリがあってよかったです。