LoginSignup
3
2

More than 3 years have passed since last update.

花粉症の重症度が分かるWEBアプリの作成~Auth0でユーザー認証~

Last updated at Posted at 2019-12-07

概要

プログラムの勉強を始めて5か月ほどの開業医です。

今回Auth0を使ったユーザー認証を勉強したので、花粉症の重症度が分かるWEBアプリに実装してみました。

花粉症(アレルギー性鼻炎)の重症度はくしゃみ・鼻水・鼻づまりの程度で判定できるので、その診断アルゴリズムをプログラミングしています。

実装

Googleアカウントを使ったユーザー認証機能。
ボタンを選択すると鼻アレルギーの重症度が分かるWEBアプリ。

完成動画

完成画像

image.png

image.png

image.png

作成方法

※完成動画と画像ではGoogleアカウントだけでなく、LINEアカウントでのユーザー認証機能も実装していますが、今回の記事ではLINEアカウント認証の実装法の説明は省いております。

1. Auth0のアカウント作成・サインイン
こちらから行ってください。
Auth0ホームページ

2. 基礎プロジェクトの作成
image.png

ログインしダッシューボードのCREATE APPLICATIONを押します。

今回は名前はMy Selfcheck AppでSingle Page Web Applicationsを選択してCREATEを押します。
image.png

今回はJavaScriptを選択します。
image.png

DOWNLOAD SAMPLEをクリックします。

image.png

1.2. 3. の設定を、Application Settingsを行います。

SAVE CHANGED で設定反映を忘れないようにします。

3.ダウンロードと解凍

image.png

ダウンロードを押します。

ZIPファイルがダウンロードされるので、自分のプロジェクトフォルダに保存します。
ZIPファイルを解凍します。

4. 移動
フォルダを移動します。

cd vanillajs-01-login/01-login
npm start

このコマンドを実行します

http://localhost:3000/ が起動します。

5. プログラム作成

サンプルの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"
    />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  </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> -->
            <!-- ブランドロゴはこちら -->
            <img
              class="mb-3 app-logo"
              src="https://self-check.net/wp-content/uploads/2019/05/Logo-e1557133216298.png"
              alt="self-check logo"
              width="150"
            />
            <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://self-check.net/wp-content/uploads/2019/05/Logo-e1557133216298.png"
              alt="self-check logo"
              width="300"
            />

            <div class="container">

              <!-- https://materializecss.com/buttons.html -->
  
              <h4>こんにちは<font color=#00bfff class="user-name" ></font>さん!</h4>
              <p></p>
              <h5>くしゃみは1日平均何回ですか?</h5>        
              <form action="#">
                      <p>
                        <label>
                          <input class="with-gap" name="group1" type="radio" value="4" checked />
                          <span>21回以上</span>
                        </label>
                      </p>
                      <p>
                        <label>
                          <input class="with-gap"name="group1" type="radio" value="3" />
                          <span>20~11回</span>
                        </label>
                      </p>
                      <p>
                        <label>
                          <input class="with-gap" name="group1" type="radio" value="2"  />
                          <span>10~6回</span>
                        </label>
                      </p>
                      <p>
                        <label>
                          <input class="with-gap" name="group1" type="radio" value="1"  />
                          <span>5~1回</span>
                        </label>
                      </p>
                      <p>
                        <label>
                          <input class="with-gap" name="group1" type="radio" value="0"  />
                          <span>0回</span>
                        </label>
                      </p>
                    </form>

              <h5>鼻をかむのは1日平均何回ですか?</h5>
              <form action="#">
                      <p>
                        <label>
                          <input class="with-gap" name="group2" type="radio" value="4" checked />
                          <span>22回以上</span>
                        </label>
                      </p>
                      <p>
                        <label>
                          <input class="with-gap"name="group2" type="radio" value="3" />
                          <span>20~11回</span>
                        </label>
                      </p>
                      <p>
                        <label>
                          <input class="with-gap" name="group2" type="radio" value="2"  />
                          <span>10~6回</span>
                        </label>
                      </p>
                      <p>
                        <label>
                          <input class="with-gap" name="group2" type="radio" value="1"  />
                          <span>5~1回</span>
                        </label>
                      </p>
                      <p>
                        <label>
                          <input class="with-gap" name="group2" type="radio" value="0"  />
                          <span>0回</span>
                        </label>
                      </p>
                    </form>

              <h5>鼻づまりはどの程度ですか?</h5>
              <form action="#">
                      <p>
                        <label>
                          <input class="with-gap" name="group3" type="radio" value="4" checked />
                          <span>1日中完全につまっている</span>
                        </label>
                      </p>
                      <p>
                        <label>
                          <input class="with-gap"name="group3" type="radio" value="3" />
                          <span>鼻づまりが非常に強く、口呼吸が1日の内かなりの時間あり</span>
                        </label>
                      </p>
                      <p>
                        <label>
                          <input class="with-gap" name="group3" type="radio" value="2"  />
                          <span>鼻閉が強く、口呼吸が1日のうち、ときどきあり</span>
                        </label>
                      </p>
                      <p>
                        <label>
                          <input class="with-gap" name="group3" type="radio" value="1"  />
                          <span>口呼吸は全くないが鼻閉あり</span>
                        </label>
                      </p>
                      <p>
                        <label>
                          <input class="with-gap" name="group3" type="radio" value="0"  />
                          <span>鼻閉なし</span>
                        </label>
                      </p>
                    </form>
              <div id="evaluation"></div>

              <button type="button">鼻アレルギーの重症度を判定</button>    

          </div>

          <div class="next-steps">
            <h5 class="my-5 text-center">自分に合ったアレルギー薬を選びましょう</h5>

            <div class="row">
              <div class="col-md-5 mb-4">
                <h6 class="mb-3">
                  <a href="https://auth0.com/docs/connections">
                    <i class="fas fa-link"></i> 花粉飛散情報はこちら
                  </a>
                </h6>
                <!-- <p>
                  リンク先の説明文
                </p> -->
              </div>

              <div class="col-md"></div>

              <div class="col-md-5 mb-4">
                <h6 class="mb-3">
                  <a href="https://auth0.com/docs/multifactor-authentication">
                    <i class="fas fa-link"></i>アレルギーのお役立ち情報はこちら
                  </a>
                </h6>
                <p>
                  <!-- <p>
                  リンク先の説明文
                  </p> -->
                </p>
              </div>
            </div>

            <div class="row">
              <div class="col-md-5 mb-4">
                <h6 class="mb-3">
                  <a href="https://auth0.com/docs/anomaly-detection">
                    <i class="fas fa-link"></i>市販の医薬品はこちら
                  </a>
                </h6>
                <p>
                  <!-- <p>
                  リンク先の説明文
                  </p> -->
                </p>
              </div>

              <div class="col-md"></div>

              <div class="col-md-5 mb-4">
                <h6 class="mb-3">
                  <a href="https://auth0.com/docs/rules">
                    <i class="fas fa-link"></i> 花粉症カレンダーはこちら
                  </a>
                </h6>
                <p>
                  <!-- <p>
                  リンク先の説明文
                  </p> -->
                </p>
              </div>
            </div>
          </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> -->
        <img
              class="mb-3 app-logo"
              src="https://self-check.net/wp-content/uploads/2019/07/9ad0bd5a51dadd4d06039943c511517d.jpg"
              alt="self-check logo"
              width="150"
            />
        <p>
          ©  katsuyukidoi 2019
        </p>

        <!-- <p>
          //画像を入れるならこちら
          <a href="">画像説明</a>
        </p> -->
      </footer>
    </div>
    <script>
     alert("鼻アレルギーの重症度を判定しましょう!");
      let severity="";

      $("#judgment").click(function() {
          score1 = $('input[name="group1"]:checked').val();
          score2 = $('input[name="group2"]:checked').val();
          score3 = $('input[name="group3"]:checked').val();

          if (score1=='4' || score2=='4' || score3=='4' ) {
              severity = "最重症";
          } else if (score1=='3' || score2=='3' || score3=='3'){
              severity = "重症";
          } else if (score1=='2' || score2=='2' || score3=='2'){
              severity = "中等症";
          } else if (score1=='1' || score2=='1' || score3=='1'){
              severity = "軽症";
          } else {
              severity = "無症状"
          }    

          $("#evaluation").html(`<h5>あなたの鼻アレルギーの重症度:${severity}</h5>`);
      });


    </script>

    <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>
  </body>
</html>

考察

Auth0はユーザー認証に必要な複雑な手順の多くを代わりにやってくれますので、今回数時間でユーザー認証機能が付いたWEBアプリを作成するとができました。
ユーザー認証があるだけでちゃんとしたアプリ感が出ると思います。
今後はユーザー情報を利用した機能を追加していきたいと思いました。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2