AngularなSPAでFacebookのOAuth認証を行う方法


はじめに

Angular な SPA(Single Page Applicaiton)で、Facebook の OAuth 認証を実現する方法のご紹介です。

始めは以下の記事と同じように、angular-oauth2-oidcというライブラリを使用して実現しようとしたのですがうまくできませんでした。

www.aruse.net

このライブラリは、XMLHttpRequest で OAuth 認証サーバーにアクセスするのですが、Facebook だとアクセスポイントと思われる URL にリクエストを投げると、CORS(Cross-Origin Resource Sharing)のエラーが発生してしまうのですよね。

しかし、Angular のngx-facebookというライブラリが見つかり、これを使えばなんとかできることが分かりました。

github.com

なお、動作確認は以下の環境で行っています。

  • Windows 10
  • Visual Studio Code
  • Angular: 7.0.0


Facebook での設定

developers.facebook.com

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化する方法は下記記事を参考にしてください。

qiita.com

画面左メニューの、アプリレビューよりアプリを公開にします。

これを行わないと、通常のユーザーでの動作確認ができません。

以上で、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 を使用しようとして、かなり苦労した上で断念しているのですけどね。💦

まあ、よいライブラリがあってよかったです。