<aside> ⚠️ かなり詳しくない状態で書いているので,間違っている情報やセキュリティ上の問題がある情報が含まれているかもしれません。その場合はご指摘いただければ幸いです。また,ご利用は自己責任でお願いいたします。

</aside>

ソーシャルログインとはSNSのアカウントを使ってユーザー認証を行うことです。「Googleアカウントでログイン」とか「Twitterでログイン」とかそういうのですね。今回はGoogleアカウントでログインをやっていみます。山形大学はG suiteを導入しており,全学生がG suiteアカウントを持っています。そのため,Googleアカウントとして山形大学のメールアドレスとパスワードをいれてもらえば認証ができるはずです。今回のワークフローとしては以下のような流れを想定しています。

<aside> 👉 Googleアカウントでログイン→IDを取得→lab.jsでIDを読み込み,参加者番号として利用

</aside>

ここでいうIDはGoogleアカウント([email protected])ではなく,ランダムに生成した英数字の羅列を指します。Googleアカウントを保存してしまうとメールアドレスが参加者番号に使用されてしまうので,匿名化を考えると面倒なためです(実験・調査の中で連絡先を聞いておくことは問題ないと思いますが,この記事の目的とは異なるので)。

このソーシャルログインをどう実装するかですが,5万/月で利用できるサービスなどがあり,お金がある場合は使ってみるといいかもしれません(が,ちょっと固定費としてはつらい・・・)。少し調べてみると,Firebaseを使うとソーシャルログインの導入が比較的かんたんにできるという情報を得ました。ということで,Firebaseでやってみました。なお,Firebaseはこのために初めて触った初心者です。

今回はGoogleアカウントでの認証を紹介しますが,Googleアカウント以外にもFacebookやTwitterなどのアカウントも利用できます。その場合は連携先のデベロッパー登録などが必要です(実用上はGoogleアカウント一択でいけるのではないでしょうか)。

  1. まず,Firebaseに移動し,「プロジェクトを作成」します

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/824ddb73-f071-459e-ab1c-b1ba8a762f03/_2021-04-13_11.48.48.png

  2. プロジェクト名は任意ですが,URLの一部になるのである程度考えた方がいいかもしれません(短いと末尾にランダムな英数字がつくのである程度長い方が見栄えはいいかも)。

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/03a9a40f-669b-4c23-831a-fb38852b5b41/_2021-04-13_11.50.06.png

  3. Googelアナリティクスは有効でも無効でもどちらでもどうぞ(無効でいいと思います)。「プロジェクトを作成」します。少し待ちます。

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/be06a752-adae-4197-88f5-e6519c3b1e98/_2021-04-13_11.51.53.png

  4. プロジェクトができたら,「続行」します。

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/959e42c9-30a7-4624-9cb8-cd6c07399d27/_2021-04-13_11.52.56.png

  5. Firebaseのコンソールに移動するので,サイドバーから「Authentication」を選びます。

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/0e1bcd62-3dca-4680-ab9a-174322c7f7a6/_2021-04-13_11.53.45.png

  6. Authenticationに移動したら,「始める」を選んでください。

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1ba63405-c083-4ea2-8794-31f7cf3ae89d/_2021-04-13_11.54.20.png

  7. 「Sign-in method」が開くので,「ログインプロバイダ」の中から,好きなものを利用できます。今回はGoogleアカウントを利用したいので「Google」を選び,「有効」にします。「サポートメール」にはメールアドレスをいれてください。

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c7d7d9a0-547c-4dc4-888f-b5488a401b03/_2021-04-13_11.57.45.png

  8. 次に「ログインプロバイダ」の下にある「承認済みドメイン」を見てください。この承認済みドメインに入っているドメインでのみ認証が動きます。3つのドメインがデフォルトで承認済みドメインに含まれています。自分が実施するオンライン実験用のドメインをここにいれておかないと動かないので,必要に応じて「ドメインを追加」しておきましょう(lab.js Builderで動作確認するためには,lab.js Builderのドメインも追加しておかないと動きません)。

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/bebeb997-0430-482b-9ac4-80a36a1140cc/_2021-04-13_12.00.12.png

  9. これでここの設定は終わりです。ちなみに,「Users」というメニューのところに,登録したユーザーが表示されることになります。

  10. 次にウェブページに設定するための情報を得るため,サイドバーから「プロジェクトの概要」を選んでください。そして,表示されたページの中の「</>」ボタンをクリックしてください。

    https://s3-us-west-2.amazonaws.com/secure.notion-static.com/5da4789d-22d1-4eca-a568-61bf5e5170be/_2021-04-13_12.04.20.png

  11. そうすると,ウェブアプリにFirebaseを追加という画面になるので,アプリのニックネームをつけて「アプリを登録」してください。Firebase hostingの設定はそのままでOKです。

  12. 「2.Firebase SDKの追加」という画面がでます。以下のようにいろいろな情報が掲載されていますが,ソーシャルログインに必要なのはapiKeyとauthDaminだけです。

    <!-- The core Firebase JS SDK is always required and must be listed first -->
    <script src="<https://www.gstatic.com/firebasejs/8.4.0/firebase-app.js>"></script>
    
    <!-- TODO: Add SDKs for Firebase products that you want to use
         <https://firebase.google.com/docs/web/setup#available-libraries> -->
    
    <script>
      // Your web app's Firebase configuration
      var firebaseConfig = {
        apiKey: "yourApiKey",
        authDomain: "your.firebaseapp.com",
        projectId: "yourProjectID-login",
        storageBucket: "your.appspot.com",
        messagingSenderId: "123456789012",
        appId: "0:123456789012:web:xxxxxxxxxxxxxxxxxxxxx"
      };
      // Initialize Firebase
      firebase.initializeApp(firebaseConfig);
    </script>
    

    ↑の中から,以下のようにapiKeyとauthDomainと初期化コマンドの部分をメモしておいてください。

    var firebaseConfig = {
      apiKey: "yourApiKey",
      authDomain: "your.firebaseapp.com",
    };
    // Initialize Firebase
    firebase.initializeApp(firebaseConfig);
    
  13. ここまででFirebaseコンソールは終わりです。次にログイン用のJavaScriptファイルとHTMLファイルを作成します。好きなテキストエディタを開き,先ほどメモしたコードを使って,以下のように書きます。このコードを「config.js」という名前で保存してください。なお,javaScpritファイルとHTMLファイルを分けてますが,「13.」の部分を「14.」のHTML内に書いてもOKです。ただ,そうすると,HTMLファイルのソースを表示するだけで,apiKeyが丸見えなので,apiKeyが含まれるところを別ファイルにしています(なお,別ファイルにしても見ようと思えば簡単に見えます)。

    よくわかってないのですが,このままだとJavaScriptファイルをアップロードした時に,apiKeyが丸見えな気がするのですが,これでいいのでしょうか?どうやらFirebase側で利用できるドメインを承認済みドメインとして制御しているからいいみたいです。

    //firebaseの初期化
    var firebaseConfig = {
        apiKey: "yourApiKey",
        authDomain: "your.firebaseapp.com",
      };
    firebase.initializeApp(firebaseConfig);
    
  14. 続いて,新たなファイルを作成し,以下のHTMLコードを書いてください。これがログイン画面用になります。「login.html」と名前をつけて,「config.js」と同じフォルダに保存してください。このコードではログインに応じてページを書き替えた上で,ユーザー名とuidを表示しています。色々やってますが,細かい挙動はコメントをみてください。

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="utf-8">
      <title>Google Login Test</title>
      <link type="text/css" rel="stylesheet" href="<https://www.gstatic.com/firebasejs/ui/4.8.0/firebase-ui-auth.css>">
    </head>
    
    <body>
      <div id="firebaseui-auth-container">
        <h3>Firebase Authentication for Google accunt</h3>
        <p>「Googleでログイン」をクリックしてください。</p>
      </div>
    
      <script src="<https://www.gstatic.com/firebasejs/8.3.0/firebase-app.js>"></script>
      <script src="<https://www.gstatic.com/firebasejs/8.3.0/firebase-auth.js>"></script>
      <!-- 日本語のUIを読み込む -->
      <script src="<https://www.gstatic.com/firebasejs/ui/4.8.0/firebase-ui-auth__ja.js>"></script>
      <script src="./config.js"></script>
      <script type="text/javascript">
        //FirebaseUIの初期化
        const ui = new firebaseui.auth.AuthUI(firebase.auth());
    
        // Firebase UIの設定
        const uiConfig = {
          callbacks: {
            signInSuccessWithAuthResult: function (authResult, redirectUrl) {
              return true;
            }
          },
          //サインインをポップアップ(popup)かリダイレクト(redirect)か
          signInFlow: 'popup',
          // ログイン完了時のリダイレクト先(今回は同じページのまま)これは省略可
          signInSuccessUrl: 'login.html',
          // Googleを認証に使用
          signInOptions: [
            firebase.auth.GoogleAuthProvider.PROVIDER_ID
          ]
        };
    
        //UIを画面に配置
        ui.start('#firebaseui-auth-container', uiConfig);
    
        //ログインステータス更新時にページを更新する
        firebase.auth().onAuthStateChanged(user => {
          //ログイン時
          if (user) {
            const message = `
                <h3>こんにちは, ${user.displayName}さん</h3>
                <p>あなたのuidは ${user.uid} です。</p>
                <p>ボタンを押すとサインアウトします。</p>
                <button type="submit"  onClick="signOut()">サインアウト</button>
                `;
            document.getElementById('firebaseui-auth-container').innerHTML = message;
            console.log('ログインしています');
          }
        });
    
        //サインアウト用
        function signOut() {
          firebase.auth().onAuthStateChanged(user => {
            firebase
              .auth()
              .signOut()
              .then(() => {
                console.log('ログアウトしました');
                location.reload();
              })
              .catch((error) => {
                console.log(`ログアウト時にエラーが発生しました (${error})`);
              });
          });
        }
      </script>
    </body>
    
    </html>