176
172

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

React アプリに Auth0 でシュッと認証を組み込んで Vercel に爆速デプロイする

Last updated at Posted at 2020-07-26

Auth0 は認証・認可サービスをクラウドで提供している SaaS ベンダーです。

「認証」という機能はどのアプリケーションにも求められる重要な要件ですが、プロダクトの本質的なビジネス価値を持たない場合が多いでしょう。Auth0 を使用することで、この「認証」機能という Undifferentiated Heavy Lifting な作業を排除できます。

本記事では、簡単な React アプリケーションを作成して Auth0 を使用した認証機能を実装します。また、作成したアプリケーションを Vercel(旧 Zeit now)にデプロイする方法を解説します。ユーザのサインアップ後の確認メールなどは SendGrid から送信されます。

以下は、本記事で紹介するアプリケーションの簡単な構成図です。また、本記事で実装されたアプリケーションは Vercel にデプロイしています。こちらからアクセスできます。ソースコードは以下の GitHub リポジトリにホストしています。

auth0-vercel.png

React アプリケーションの雛形を作る

まずは create-react-app を使用して簡単なアプリケーションを実装していきます。

$ create-react-app app --typescript

react-router

$ yarn add react-router react-router-dom
$ yarn add -D @types/react-router @types/react-router-dom

最初の react-router はシームレスなナビゲーションを可能にするメインのライブラリです。ふたつめは react-router-dom で、React ルーターの DOM 結合を提供します。-D オプションをつけることで開発時にのみ使用するライブラリをインストールできます。この例では TypeScript の型定義ライブラリをインストールしています。

react-bootstrap

最低限のデザインを整えるために react-bootstrap を使用します。

$ yarn add react-bootstrap react-bootstrap-icons bootstrap
$ yarn add -D @types/react-bootstrap

auth0-react

Auth0 の SDK である auth0-react をインストールします。後述しますが、従来の auth0-spa-js などに比べると Hooks 化の対応が進んでおり、本当に最小限のコードで認証機能を実装できます。

$ yarn add @auth0/auth0-react

auth0-react を使用して認証機能を実装する

auth0-react の公式ドキュメント でも解説していますが、本記事ではもう少し実際の開発のユースケースを想定してガイドします。

Auth0Provider

まずは index.tsx にて <App/> コンポーネントを <Auth0Provider/> でラップします。このようにしておくことで、 <App/> コンポーネント内で useAuth0 フックを使用できるようになります。 useAuth0 フックを使用することで、以下のような様々な認証に関するステートおよびメソッドを取得することができます。

  • ステートの例: isLoading, isAuthenticated, user
  • メソッドの例: loginWithRedirect, logout
index.tsx
import React from "react";
import ReactDOM from "react-dom";
import { Auth0Provider } from "@auth0/auth0-react";
import "bootstrap/dist/css/bootstrap.min.css";
import { App } from "./App";

ReactDOM.render(
  <Auth0Provider
    domain={process.env.REACT_APP_AUTH0_DOMAIN!}
    clientId={process.env.REACT_APP_AUTH0_CLIENT_ID!}
    redirectUri={window.location.origin}
  >
    <App />
  </Auth0Provider>,
  document.querySelector("#root")
);

domain および、clientId には Auth0 のマネジメントコンソール画面で作成した Application の domain, clientId を入力してください。

image.png

LoginButton

ログインボタンは useAuth0 フックを使用すると簡単に実装できます。loginWithRedirect メソッドを実行すると Auth0 の SSO エンドポイントを使用してログインした後に、自身のアプリケーションにリダイレクトします。

LoginButton.tsx
import React from "react";
import { useAuth0 } from "@auth0/auth0-react";
import { Button } from "react-bootstrap";

function LoginButton() {
  const { isAuthenticated, loginWithRedirect } = useAuth0();

  return !isAuthenticated ? (
    <Button onClick={loginWithRedirect}>Log in</Button>
  ) : null;
}

export default LoginButton;

実際にログインボタンを押した振る舞いは以下のようになります。
login.gif

ログイン処理の際、Auth0 のエンドポイントにアクセスし、自身のアプリケーションにリダイレクトします。事前に Application URIs の各種設定をしておきましょう。以下の例では開発用に localhost:3000、 本番デプロイ用として https://auth0-todo-app.vercel.app/ を設定しています。

image.png

LogoutButton

ログアウト処理には logout メソッドが用意されています。
ログアウト後に表示するパスを returnTo: xxxx で指定します。

LogoutButton.tsx
import React from "react";
import { useAuth0 } from "@auth0/auth0-react";
import { Button } from "react-bootstrap";

function LogoutButton(props: any) {
  const { isAuthenticated, logout } = useAuth0();

  return isAuthenticated ? (
    <Button
      variant="outline-primary"
      onClick={() => {
        logout({ returnTo: window.location.origin });
      }}
      {...props}
    >
      Log out
    </Button>
  ) : null;
}

export default LogoutButton;

UserProfile

ログインユーザの情報は user を使用して取得します。認証プロバイダー(Google, Facebook, etc...)によって取得できる情報は異なります。以下では、ログインユーザのアバター画像を user.picture として取得しています。

UserProfileAvatar.tsx
import React from "react";
import { useAuth0 } from "@auth0/auth0-react";
import { Image } from "react-bootstrap";
export const UserProfileAvatar = (props: any) => {
  const { user } = useAuth0();
  return (
    <Image
      style={{ width: "30px" }}
      src={user.picture}
      roundedCircle
      {...props}
    />
  );
};

この記事のサンプルアプリケーションでは、この情報を組み合わせて、ユーザアイコンをクリックすると各種メニューが表示されるようにしています。

image.png

認証済みのユーザだけ見れるページを制御する

react-router-dom を使用した実装ではおなじみの PrivateRoute を組み込んでいきます。
auth0-react では、ログインしていないユーザが表示しようとすると、ログインページにリダイレクトする withAuthenticationRequired() が用意されています。

以下のように ProtectedRoute のようなルート制御コンポーネントを作成しておくと便利です。

ProtectedRoute.tsx
import { withAuthenticationRequired } from "@auth0/auth0-react";
import React from "react";
import { Route } from "react-router-dom";

export function ProtectedRoute({ component, ...args }: any) {
  return (
    <Route component={withAuthenticationRequired(component, {})} {...args} />
  );
}

ルート制御ではこの ProtectedRoute コンポーネントを使用して、ログインしていないユーザがアクセスできないページを実装できます。以下の例では、/profile はログインしていない状態では表示できません。

App.tsx
import React from "react";
import { useAuth0 } from "@auth0/auth0-react";
import { Route, BrowserRouter as Router, Switch } from "react-router-dom";
import Home from "./pages/Home";
import { ProtectedRoute } from "./components/auth/ProtectedRoute";
import Profile from "./pages/Profile";
import { Layout } from "./components/layout/Layout";
import Support from "./pages/Support";
export function App() {
  const { isLoading } = useAuth0();
  if (isLoading) {
    return <p></p>;
  }

  return (
    <Router>
      <Layout>
        <Switch>
          <Route path="/" exact component={Home} />
          <ProtectedRoute path="/profile" component={Profile} />
          <Route path="/support" exact component={Support} />
        </Switch>
      </Layout>
    </Router>
  );
}

/profile にアクセスしようとするとログインページにリダイレクトされています。

protectedroute.gif

Vercel にデプロイする

Vercel のダッシュボードから Import Project をクリックします。

image.png

今回は GitHub にホスティングしているソースコードを元にデプロイするので、Git リポジトリを選択します。

image.png

GitHub のリポジトリ URL を指定してください。
image.png

最後にビルドコマンドと環境変数を設定します。
Auth0 の domain と clientId は環境変数に指定して React アプリに渡しましょう。

image.png

あとは Deploy ボタンをクリックして完了です。これだけでデプロイができるはずです。

サインアップ後の確認メールを SendGrid から送信する

Auth0 には Welcome メールやパスワードリセット、アカウントの検証などのためにメールを送信する仕組みが用意されています。

image.png

送信するためには事前にメールプロバイダの設定が必要です。今回は無料で提供されている SendGrid を使用してみましょう。

Email Provider の画面から  SendGrid  を選択し、送信元メールアドレス(From)と SendGrid の API キーを入力します。API キーは SendGrid の settings から発行できます。

image.png

ログインに成功すると以下のようなメールが送信されるようになります。

image.png

まとめ

Auth0 + Vercel + SendGrid という構成をチュートリアル的に実装し、その振る舞いを確認してみました。auth0-react ライブラリは非常に使い勝手がよく、簡単に認証機能を組み込むことができます。一連の流れを実装しても 1 ~ 2 時間で実装できました。以前までは苦労して認証の仕組みを整えていましたが随分と楽になりそうです。

176
172
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
176
172

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?