超初心者がAuth０でログイン機能を実装した

##はじめに
プログラミングを学び始めてから2か月の初心者です。最近は初心者でも出来る色んな技にチャレンジして体感しながら勉強しています。というわけで、今回はと～っても面倒なログイン機能を「さささ～」という感じで実装できちゃうAuth0を使ってみました。
##Auth0とは？（超初心者的解釈）
Auth0とはWebやスマホアプリに対して認証機能をクラウドを介して提供してくれるサービスのこと。有難いことにLine,Google, Facebook, Twitterなど有名どころのSNSと既に連携していて、簡単な操作でそれらを使ったログイン機能を自分のWEBに付加することが出来ます。
初心者的に有難いことにはサイトを作る前からログイン機能だけテストが出来たり、サンプルサイトを用意してくれていたりとても親切。しかも一定時間・量までは無料なので助かります。
詳細は[こちら](https://qiita.com/furuth/items/68c3caa3127cbf4f6b77)でも紹介されています。
##目指すもの
年末ということで引き続き、カレンダーをテーマにすることにしました。
Auth0を使ってLineやGoogleのアカウントを使ってログインすると
アカウント写真付きのカレンダーを表示します。
##環境
Node.js v10.16.3
Windows 10 pro
Visual Studio Code v1.39.1
Auth0
Bootstrap
##方法
1.まずは[Auth0のサイト](https://auth0.com/jp/)にてサインインからアカウントを作成します。
　登録したメールにVerifyメールが来るので迷惑メールに入らないように気を付けます。
2.サインイン出来たら+Create Application→Nameに適当な名前
　→Single Page Web Applications→Createをクリック
3.黄色のJavaScriptを選択したのち、オレンジのDownload sampleをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508834/0d946a37-f627-8934-98b6-7e267492487b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508834/5a01693c-9244-1764-109b-a01d867d0200.png)
4.こちらの赤枠のApplication Settingsを別タブで開き、下記の情報を参照しながら入力していきます。終わったら下の方にある水色のSAVE CHANGESをクリックして保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508834/6f536915-5d2e-436a-3738-28cbb5b7d799.png)
5.すると元の画面に戻りオレンジのDownloadボタンをクリックし、ダウンロードされたファイルを解凍（展開）しておきます。
6．Visual Studio Codeで解凍したファイルを開きます。New Terminalを開き、まずは下記でフォルダを移動

```js
cd vanillajs-01-login/01-login

```
7.インストールを実施

```js
npm i
```
8.今回はあらかじめ設定されているローカルサーバーをスタート

```js
npm start
```
9．[こちら](https://dev.classmethod.jp/server-side/auth0/line-login/#toc-line-login1)を参照にしながらLINEのログイン機能も追加。Auth側への情報はチャンネルIDやシークレットトークンが必要。入力してSAVEするとTRYというボタンが出てくるので、ログイン可能か確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508834/53d35b0b-958e-64fd-1c1f-60378215a2f3.png)
10.基本的に```index.html```ファイルを変更して遊ぶ。今回は私の場合はカレンダーを出力したかったので[こちら](https://liginc.co.jp/355474)を参考にいたしました。またスタイルシートの部分についてはこちらはBootstrapが使われていたのでその[ホームページ](https://getbootstrap.com/docs/4.0/getting-started/introduction/)で調べながら変更しています。
##コード
```html
<!DOCTYPE html>
<html class="h-100">
  <head>
    <meta charset="UTF-8" />
    <title>SPA SDK Sample</title>
    <link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
    />
    <link rel="stylesheet" type="text/css" href="/css/auth0-theme.min.css" />
    <link rel="stylesheet" type="text/css" href="/css/main.css" />
    <link
      rel="stylesheet"
      href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/styles/monokai-sublime.min.css"
    />
    <link
      rel="stylesheet"
      href="https://use.fontawesome.com/releases/v5.7.2/css/solid.css"
      integrity="sha384-r/k8YTFqmlOaqRkZuSiE9trsrDXkh07mRaoGBMoDcmA58OHILZPsk29i2BsFng1B"
      crossorigin="anonymous"
    />
    <link
      rel="stylesheet"
      href="https://use.fontawesome.com/releases/v5.7.2/css/fontawesome.css"
      integrity="sha384-4aon80D8rXCGx9ayDt85LbyUHeMWd3UiBaWliBlJ53yzm9hqN21A+o1pqoyK04h+"
      crossorigin="anonymous"
    />

    <link
      rel="stylesheet"
      href="https://cdn.auth0.com/js/auth0-samples-theme/1.0/css/auth0-theme.min.css"
    />
    <style>
    .calendar-title {
    text-align: left;
    }
    </style>
  </head>

  <body class="h-100">
    <div id="app" class="h-100 d-flex flex-column">
      <div class="nav-container">
        <nav class="navbar navbar-expand-md navbar-light bg-light">
          <div class="container">
            <div class="navbar-brand logo"></div>
            <button
              class="navbar-toggler"
              type="button"
              data-toggle="collapse"
              data-target="#navbarNav"
              aria-controls="navbarNav"
              aria-expanded="false"
              aria-label="Toggle navigation"
            >
              <span class="navbar-toggler-icon"></span>
            </button>

            <div class="collapse navbar-collapse" id="navbarNav">
              <ul class="navbar-nav mr-auto">
                <li class="nav-item">
                  <a href="/" class="nav-link route-link">Home</a>
                </li>
              </ul>
              <ul class="navbar-nav d-none d-md-block">
                <!-- Login button: show if NOT authenticated -->
                <li class="nav-item auth-invisible">
                  <button
                    id="qsLoginBtn"
                    onclick="login()"
                    class="btn btn-primary btn-margin auth-invisible hidden"
                  >
                    Log in
                  </button>
                </li>
                <!-- / Login button -->

                <!-- Fullsize dropdown: show if authenticated -->
                <li class="nav-item dropdown auth-visible hidden">
                  <a
                    class="nav-link dropdown-toggle"
                    href="#"
                    id="profileDropDown"
                    data-toggle="dropdown"
                  >
                    <!-- Profile image should be set to the profile picture from the id token -->
                    <img
                      alt="Profile picture"
                      class="nav-user-profile profile-image rounded-circle"
                      width="50"
                    />
                  </a>
                  <div class="dropdown-menu">
                    <!-- Show the user's full name from the id token here -->
                    <div class="dropdown-header nav-user-name user-name"></div>
                    <a
                      href="/profile"
                      class="dropdown-item dropdown-profile route-link"
                    >
                      <i class="fas fa-user mr-3"></i> Profile
                    </a>
                    <a
                      href="#"
                      class="dropdown-item"
                      id="qsLogoutBtn"
                      onclick="logout()"
                    >
                      <i class="fas fa-power-off mr-3"></i> Log out
                    </a>
                  </div>
                </li>
                <!-- /Fullsize dropdown -->
              </ul>

              <!-- Responsive login button: show if NOT authenticated -->
              <ul class="navbar-nav d-md-none auth-invisible">
                <button
                  class="btn btn-primary btn-block auth-invisible hidden"
                  id="qsLoginBtn"
                  onclick="login()"
                >
                  Log in
                </button>
              </ul>
              <!-- /Responsive login button -->

              <!-- Responsive profile dropdown: show if authenticated -->
              <ul
                class="navbar-nav d-md-none auth-visible hidden justify-content-between"
                style="min-height: 125px"
              >
                <li class="nav-item">
                  <span class="user-info">
                    <!-- Profile image should be set to the profile picture from the id token -->
                    <img
                      alt="Profile picture"
                      class="nav-user-profile d-inline-block profile-image rounded-circle mr-3"
                      width="50"
                    />
                    <!-- Show the user's full name from the id token here -->
                    <h6 class="d-inline-block nav-user-name user-name"></h6>
                  </span>
                </li>
                <li>
                  <i class="fas fa-user mr-3"></i>
                  <a href="/profile" class="route-link">Profile</a>
                </li>

                <li>
                  <i class="fas fa-power-off mr-3"></i>
                  <a href="#" id="qsLogoutBtn" onclick="logout()">Log out</a>
                </li>
              </ul>
            </div>
          </div>
        </nav>
      </div>

      <div id="main-content" class="container mt-5 flex-grow-1">
        <div id="content-home" class="page">
          <div class="text-center hero">
            <img
              class="mb-3 app-logo"
              src="https://1.bp.blogspot.com/-RJRt_Hv37Kk/VMIu-CCBpII/AAAAAAAAq2E/JsIJ8pPwmuY/s400/calender_takujou.png"
              alt="JavaScript logo"
              width="75"
            />
            <h1 class="mb-1 text-warning">Calendar Sample Project</h1>
            
            <p class="lead text-center">
              カレンダーを作ってみよう
            </p>
          </div>
          <h2 class="mb-4 text-center">
                  <a class="lead auth-visible hidden">
                    <i class="text-center"></i> カレンダー例
                  </a>
                <a class="auth-visible hidden">
                  <img
                  alt="Profile picture"
                  class="nav-user-profile profile-image rounded-circle"
                  width="100"
                  />
                </a>
                <h6 class="calendar-title text-center auth-visible hidden"><span id="js-year"></span>年 <span id="js-month"></span>月</h6>
                <div class="mx-auto auth-visible hidden" style="width: 200px;">
                <table class="calendar-table">
                  <thead>
                    <tr>
                      <th>日</th>
                      <th>月</th>
                      <th>火</th>
                      <th>水</th>
                      <th>木</th>
                      <th>金</th>
                      <th>土</th>
                    </tr>
                  </thead>
                  <tbody id="js-calendar-body"></tbody>
                  
                </table>
              </div>
              </h2>
              </div>              
            </div>

        <div class="page" id="content-profile">
          <div class="container">
            <div class="row align-items-center profile-header">
              <div class="col-md-2">
                <img
                  alt="User's profile picture"
                  class="rounded-circle img-fluid profile-image mb-3 mb-md-0"
                />
              </div>
              <div class="col-md">
                <h2 class="user-name"></h2>
                <p class="lead text-muted user-email"></p>
              </div>
            </div>

            <div class="row">
              <pre class="rounded">
                <code id="profile-data" class="json"></code></pre>
            </div>
          </div>
        </div>
      </div>

      <footer class="bg-light text-center p-5">
        <div class="logo"></div>
        <p>
          Sample project provided by
          <a href="https://auth0.com">MARUKO</a>
        </p>
      </footer>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>
    <script src="js/auth0-theme.min.js"></script>
    <script src="https://cdn.auth0.com/js/auth0-spa-js/1.2/auth0-spa-js.production.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/highlight.min.js"></script>
    <script src="js/ui.js"></script>
    <script src="js/app.js"></script>
    <script>
    var $window = $(window);
      var $year = $('#js-year');
      var $month = $('#js-month');
      var $tbody = $('#js-calendar-body');

      var today = new Date();
      var currentYear = today.getFullYear(),
        currentMonth = today.getMonth();

      $window.on('load', function () {
        calendarHeading(currentYear, currentMonth);
        calendarBody(currentYear, currentMonth, today);
      });

      function calendarBody(year, month, today) {
        var todayYMFlag = today.getFullYear() === year && today.getMonth() === month ? true : false; // 本日の年と月が表示されるカレンダーと同じか判定
        var startDate = new Date(year, month, 1); // その月の最初の日の情報
        var endDate = new Date(year, month + 1, 0); // その月の最後の日の情報
        var startDay = startDate.getDay();// その月の最初の日の曜日を取得
        var endDay = endDate.getDate();// その月の最後の日の曜日を取得
        var textSkip = true; // 日にちを埋める用のフラグ
        var textDate = 1; // 日付(これがカウントアップされます)
        var tableBody = ''; // テーブルのHTMLを格納する変数

        for (var row = 0; row < 6; row++) {
          var tr = '<tr>';

          for (var col = 0; col < 7; col++) {
            if (row === 0 && startDay === col) {
              textSkip = false;
            }
            if (textDate > endDay) {
              textSkip = true;
            }
            var addClass = todayYMFlag && textDate === today.getDate() ? 'is-today' : '';
            var textTd = textSkip ? ' ' : textDate++;
            var td = '<td class="' + addClass + '">' + textTd + '</td>';
            tr += td;
          }
          tr += '</tr>';
          tableBody += tr;
        }
        $tbody.html(tableBody);
      }

      function calendarHeading(year, month) {
        $year.text(year);
        $month.text(month + 1);
      }
        var today = new Date();
        var currentYear = today.getFullYear(),
          currentMonth = today.getMonth();
    </script>
  </body>
</html>

```
##結果
ログイン前はこのような何もないホームページですが
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508834/70851a4d-d69f-edef-76c4-2371086c3eb1.png)

ログインを経て
![2019-12-08_01h40_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508834/96cf98f6-adb4-0e4e-6f5b-264a3ea31b70.png)

写真付きのカレンダーが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508834/53acf70f-a4ee-ef60-1e61-4df810b012e2.png)

##感想
提供されているサンプルバージョンを参考にしながら、単純ですがログイン前とログイン後の違いを出すような仕組みを作ることが出来ました。こちらのAuth0のサンプルページが非常にシンプルかつ応用しやすいコードになっていたので、手探りでテストしながらイメージのものに少しづつ近づけることが出来ました。万が一、壊しても再度サイトからダウンロードすればよいだけなので初心者にはとてもお勧めです。