はじめに
今回はRailsのAPIモードとNext.jsを利用したSPA構成に、Auth0で認証機能をサクッと開発していきます。
Auth0は導入が簡単かつチュートリアルやドキュメントが豊富なので、初めての人でも簡単に認証機能を実装することができます。
直近で自分が行った新規開発案件でもAuth0が採用されることが多かったです。
なおAuth0についての詳しい解説は本記事では割愛するので気になった方は、こちらを確認してみてください。
またAuth0とFirebase Authenticationといった他の認証機能との比較記事はこちらで確認してみてください。
本記事で解説する内容はAuth0の公式ドキュメントに沿って解説していきます。
この記事の対象者
- Next.js×Auth0で認証機能を開発したい
- RailsのAPIモードでAuth0の認証機能を開発したい
- Rails×Next.jsで認証機能(新規登録・ログイン・ログアウト)を開発したい
- 手を動かしながらAuth0を理解したい
- SPAで認証機能を持つアプリを開発したい
フロント側(Next.js側)の開発
まずはフロント側でのAuth0の実装をしていきます。
Next.jsプロジェクトの環境構築
nodeやyarnの環境構築されているものとして進めていきます。
またフロント側はauth0-front、バックエンド側はauth0-backという名前でプロジェクトを作成します。(これは任意です)
さっそく下記のコマンドでNext.js×TypeScriptの環境を作成します。
npx create-next-app auth0-front --typescript
終わったらdev環境を立ち上げます
npm run dev
こちらが表示されていたら、Next.js×TypeScriptのプロジェクトの環境構築は完了です。
Auth0でのプロジェクト作成
次にAuth0側での設定を進めていきます。
こちらは公式ドキュメントを元に解説を進めていきます。
まず初めにAuth0の公式サイトへアクセスしGoogleログイン等でAuth0へのアカウント作成を行います。
今回は個人で開発として進めるのでPersonal
を選択します。
次に「+Create Application」からAuth0を利用する新規にプロジェクトを作成します。
開発するアプリ名を入れて、Single Page Web Applicationsを今回は選択します。
次にsettingより「Domain」「Client ID」を確認しておきます。
こちらは後でNext.jsの環境変数として設定します。
コールバック用のURLを設定する
setting画面で下にスクロールすると「Application URIs」という項目が出てくるので該当の箇所にURLを入力していきます。
はじめにAuth0での認証完了後にユーザーのリダイレクト先を設定します。
なおフロント側のポート番号は9000、バックエンド側は3000で設定します。(設定は後で行います)
http://localhost:9000/login
このように設定することでフロント側でAuth0経由でのログイン処理完了後にhttp://localhost:9000/login
のページへ遷移することができます。
※ ログイン後なのでhttp://localhost:9000/home
等で設定した方が見やすかったかもしれないです。(追記)
実際の遷移先ページの実装はこの後やります。
ログアウト用のURLを設定
こちらも同様に以下のURLを設定します。
http://localhost:9000/
Allowed Web OriginsとAllowed Origins (CORS)
最後にAllowed Web OriginsとAllowed Origins (CORS)の2つを設定します。
こちらも今までと同様に以下のURLを入れます。
http://localhost:9000/
以上でAuth0側での設定は完了です。
Next.jsでのAuth0の準備
次にNext.jsと今準備をしたAuth0の連携を進めていきます。
SDKをインストール
はじめにAuth0 React SDKをインストールするために以下のコマンドを実行します。
npm install @auth0/auth0-react
Auth0Providerコンポーネントを設定する
Auth0 React SDKではReact Contextを利用することで認証状態を管理することができます。
先程インストールした@auth0/auth0-react
からAuth0Provider
をimport
してNext.jsアプリをラップします。
またその際に先程Auth0のsetting画面で確認した「domain」「client_id」を環境変数に定義しておきます。(後述)
process.env["NEXT_PUBLIC_AUTH0_AUDIENCE"]
の値はRails側の環境構築完了後に.env
に記載するので一旦空の値になっていても大丈夫です。
import "../styles/globals.css";
import { Auth0Provider } from "@auth0/auth0-react";
function MyApp({ Component, pageProps }) {
//ログイン後のリダイレクト先を指定
const redirectUri = `${process.env["NEXT_PUBLIC_BASE_URL"]}/login`;
return (
<Auth0Provider
domain={process.env["NEXT_PUBLIC_AUTH0_DOMAIN"]!}
clientId={process.env["NEXT_PUBLIC_AUTH0_CLIENT_ID"]!}
audience={process.env["NEXT_PUBLIC_AUTH0_AUDIENCE"]!}
redirectUri={redirectUri}
>
<Component {...pageProps} />
</Auth0Provider>
);
}
export default MyApp;
環境変数は下記のように設定をします。
xxxx
には先程Auth0のsetting画面で確認した値を入れてください。
NEXT_PUBLIC_BASE_URL='http://localhost:9000'
NEXT_APP_REST_URL="http://localhost:3000/api/v1"
NEXT_PUBLIC_AUTH0_DOMAIN='xxxxxxxxxxxxxxxxx'
NEXT_PUBLIC_AUTH0_CLIENT_ID='xxxxxxxxxxxxxxxxx'
ポート番号を変更する
最後にNext.js側のポート番号を9000に変更します。
package.json
ファイルのdevを以下の変更することでポート番号を9000することができます。
"scripts": {
"dev": "next dev -p 9000",
"build": "next build",
},
実際に確認します。
npm run dev
ポート番号が9000のローカル環境が立ち上がることが確認できるかと思います。
以上でNext.jsアプリでAuth0を使う準備が完了しました。
ログイン機能を作成する
ログイン後に遷移するページを作成する
import { useAuth0 } from "@auth0/auth0-react";
import { NextPage } from "next";
import React from "react";
const LoginPage: NextPage = () => {
const { isAuthenticated } = useAuth0();
return (
<div>
<h2>ログイン状態</h2>
{isAuthenticated ? <p>ログイン中です</p> : <p>ログアウトしています</p>}
</div>
);
};
export default LoginPage;
useAuth0
のisAuthenticated
でログイン状態なのかを判定してくれます。
現状はログインをしていないのでlocalhost:9000/login
にアクセスした時に、「ログアウトしています」と表示されることが確認できます。
Homeページにログイン機能を追加する
次にログイン機能を実装します。
import { useAuth0 } from "@auth0/auth0-react";
export default function Home() {
const { loginWithRedirect } = useAuth0();
return (
<div>
<button onClick={() => loginWithRedirect()}>ログイン</button>
</div>
);
}
npm run dev
これによって、画面にログインボタンが表示されていることが確認できます。
実際にボタンをクリックすると以下のように Auth0側のログイン画面に遷移することが確認できます。
Googleアカウントでログインすると以下のような画面が表示されるのでAcceptをすればログイン(新規登録)が完了します。
完了後は先程作成したlogin画面に遷移していることを確認できるかと思います。
Homeページにログアウトボタンを追加する
先程作成したpages/login.tsx
においてログイン中だった場合のみログアウトボタンを表示させログアウト処理が行えるように書き換えます。
import { useAuth0 } from "@auth0/auth0-react";
import { NextPage } from "next";
import React from "react";
const LoginPage: NextPage = () => {
const { isAuthenticated, logout } = useAuth0();
return (
<div>
<h2>ログイン状態</h2>
{isAuthenticated ? (
<>
<p>ログイン中です</p>
<button onClick={() => logout({ returnTo: window.location.origin })}>
ログアウト
</button>
</>
) : (
<p>ログアウトしています</p>
)}
</div>
);
};
export default LoginPage;
実際にログアウトボタンをクリックすると文言が変わっていることが確認できます。
以上でフロント側での新規登録、ログイン、ログアウトの実装が完了しました。
次にRailsのAPIモード側のAuth0の設定をしていきます。
バックエンド側(Rails側)の開発
バックエンド側もフロントと同様にAuth0での設定をした上でRailsアプリ側で実装を進めていきます。
こちらのドキュメントの流れで解説をしていきます。
Auth0側の設定
まずはじめにApplications > APIsからcreate APIをクリックします。
該当項目を入力しcreateをクリックします。
ドメイン情報を取得するためTest > urlからドメイン情報を確認します。
urlの.comまでがドメイン情報になっています。
これでauth0側の設定は完了なのでRailsアプリの設定をしていきます。
APIモードでRailsアプリを環境構築
auth0-backというディレクトリ名でアプリを開発していきます。
rails new auth0-back --api
以下をgemファイルに追加してbundle install
をします。
gem 'dotenv-rails'
gem 'jwt'
gem 'rack-cors'
-
dotenv-rails
は環境変数を設定するためのgem -
JsonWebToken
を利用してAccess Token
の検証をするのでjwt
を使う -
rack-cors
はcors
の設定を行うために使います
CORSについてはこちらを確認してみてください。
環境変数を定義する
先程のAuth0側で確認したdomain
とidentifier
をこちらに格納します。
AUTH0_DOMAIN="xxxxxxxxx"
AUTH0_IDENTIFIER="xxxxxxxxx"
identifier
に関してはAuth0の管理画面から確認できます。
またidentifier
の値はフロント側の.env
にも後で記載します。
JWTクラスを作成する
こちらはドキュメントの記述をそのまま流用します。
処理内容は公式ドキュメントに書いてある通り、リクエストのAuthorization
のヘッダーから取得したAccess Token
をデコードするJsonWebToken
クラスを作成しています。
これでAuth0テナントの公開鍵を取得し、トークンの検証をすることができる。
# lib/json_web_token.rb
# frozen_string_literal: true
require 'net/http'
require 'uri'
class JsonWebToken
def self.verify(token)
JWT.decode(token, nil,
true, # Verify the signature of this token
algorithms: 'RS256',
iss: 'https://dev-k4qwtrhp.jp.auth0.com/',
verify_iss: true,
aud: Rails.application.secrets.auth0_api_audience,
verify_aud: true) do |header|
jwks_hash[header['kid']]
end
end
def self.jwks_hash
jwks_raw = Net::HTTP.get URI("https://dev-k4qwtrhp.jp.auth0.com/.well-known/jwks.json")
jwks_keys = Array(JSON.parse(jwks_raw)['keys'])
Hash[
jwks_keys
.map do |k|
[
k['kid'],
OpenSSL::X509::Certificate.new(
Base64.decode64(k['x5c'].first)
).public_key
]
end
]
end
end
認証用のクラスを作成する
認証のロジックを抽出することでJWTの真正性を検証する処理とHTTPリクエストを認証する処理を分離している。
class AuthorizationService
def initialize(headers = {})
@headers = headers
end
def current_user
@auth_payload, @auth_header = verify_token
@user = User.from_token_payload(@auth_payload)
end
private
def http_token
@headers['Authorization'].split(' ').last if @headers['Authorization'].present?
end
def verify_token
JsonWebToken.verify(http_token)
end
end
-
AuthorizationService
-
Authorization HTTP Header
に含まれるアクセストークンを取得しJWTに渡して検証する
-
-
verify_token
-
json_web_token.rb
を実行してTokenを渡す
-
-
current_user
- ユーザーモデルメソットを実行し、ユーザー情報を返す
SecuredControllerを作成する
APIエンドポイントのセキュリティー確保を行うsecured_controlle
を作成する。
こちらに関しても同様にAuth0のドキュメントを参考に記述をします。
class SecuredController < ApplicationController
before_action :authorize_request
private
def authorize_request
authorize_request = AuthorizationService.new(request.headers)
@current_user = authorize_request.current_user
rescue JWT::VerificationError, JWT::DecodeError
render json: { errors: ['Not Authenticated'] }, status: :unauthorized
end
end
SecuredController
クラスhaApplicationController
を継承しており、全てのコントローラー実行前にauthorize_request
を実行します。
authorize_request
ではtokneを解析し、ユーザー認証ができなかった場合はエラーメッセージを返すようなメソットです。
最後にParameter Wrapping
を無効にするために以下のような記述をします。
wrap_parameters format: []
以上でRails側でのAuth0の準備は完了しました。
モデルを作成する
次にAuth0を利用してユーザーモデルを作成します。
今回はブログ投稿型のアプリを開発するというて程で、Auth0の認証機能を使っていきます。
実際に行う内容は下記の内容です
- ブログの新規作成は認証済みユーザーだけができる
- ブログの閲覧は認証していないユーザーもできる
ユーザーモデルの作成
まずは以下のコマンドでユーザーモデルを作成します。
rails g model User
マイグレーションファイルを以下のように書きます。
class CreateUsers < ActiveRecord::Migration[6.1]
def change
create_table :users do |t|
t.string :sub, null: false
t.timestamps
end
end
end
subはユーザーidが入ってきます。
またユーザーとブログ記事は1:N
の関係でリレーションが結ばれているので、ユーザーモデルを下記のように書き換えます。
class User < ApplicationRecord
has_many :posts, dependent: :destroy
def self.from_token_payload(payload)
find_by(sub: payload['sub']) || create!(sub: payload['sub'])
end
end
self.from_token_payload(payload)
ではtoken
情報を参照して対象のuser
が存在する場合はuser
情報を返し、存在しない場合は新規作成の処理を行いまう。
ブログ記事のモデルを作成する
次にブログ記事のモデルを作成していきます。
rails g model Post user:references title:string caption:text
マイグレーションを実行します。
rails db:migrate
ブログ記事のコントローラーを作成
- ブログの取得(
index,show
)は認証なしで実行できる - ブログの新規作成は認証がないと実行できない
- ブログの削除も認証がないと実行ができない
authorize_request
の処理はapp/controllers/secured_controller.rb
に記述済み。
class Api::V1::PostsController < SecuredController
skip_before_action :authorize_request, only: [:index,:show]
def index
posts = Post.all
render json: posts
end
def show
post = Post.find(params[:id])
render json: post
end
def create
# ユーザー認証
post = @current_user.posts.build(post_params)
if post.save
render json: post
else
render json: post.errors, status: :unprocessable_entity
end
end
def destroy
post = Post.find(params[:id])
post.delete
end
private
def post_params
params.permit(:title,:caption)
end
end
skip_before_action
でindexとshowメソットのみ認証処理をスキップしている。
ルーターの設定
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :posts
end
end
end
Postmanを利用してAPIコールを試す
Postmanの準備に関しては割愛します。まだの方はこちらを参考に準備をしてください。
トークンを入れずに新規作成(POST)を試す
はじめにトークンを入れずにPostmanでブログ記事の新規作成を試します。
Railsのサーバーを立ち上げます。
rails s
- POSTを選択肢して
http://127.0.0.1:3000/api/v1/
を入れます - Paramsを選択肢
title
とcaption
に値を入れます - その上でSendボタンを押します
- トークンを入れていないので結果として"Not Authenticated"が返ってきます
以下のファイルのauthorize_request
の処理が実行されていることが確認できます。
Tokne
を付与していないのでerror
が処理が走っています。
class SecuredController < ApplicationController
before_action :authorize_request
private
def authorize_request
authorize_request = AuthorizationService.new(request.headers)
@current_user = authorize_request.current_user
rescue JWT::VerificationError, JWT::DecodeError
render json: { errors: ['Not Authenticated'] }, status: :unauthorized
end
end
トークンを入れて新規作成(POST)を試す
次にトークンを入れて新規作成のメソットを実行してみます。
まずAuth0の管理画面を開きTokenを取得します。管理画面のTestタブの下記の部分よりTokenを取得します。
長いのでコピーする際は注意してください。
次にpostman側で取得したTokenを格納していきます。
Authorizationのタブを選択肢TypeをBearer Token
に設定します。
右側のTokneの中に先ほどAuth0から取得した値を貼り付けます。
これで準備は完了なので先程と同様にparamに値をいれPOSTを叩いてみます。
データが実際に登録されて、レスポンスが返ってきてることが確認できます。
取得(GET)メソットを試す
次にGETメソットを実行して、先ほど新規作成した記事が実際に登録されているかを確認します。
Tokenを空にしてもGETメソットはレスポンスは返ってきます。
削除(DLETE)メソットを試す
idが2のデータの記事を削除する処理を行います。
こちらはTokneの値を入れないと認証エラーになります。
GETメソットを実行するとidが2のデータが削除されていることが確認できます。
以上でRails側のCRUDの確認が完了しました。
フロントとバックエンドの連携
最後にRailsとNext.jsの連携を進めていきます。
概要としては以下の内容を行います。
- フロント側でログイン処理をする
- ログイン後に付与されるTokneをフロント側のstateで管理する
- Token情報を付与しフロント側からリクエストを送る
Rails側の設定
フロント側からのアクセスを許可するためにcorsの設定をおこないます。
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'http://localhost:9000'
resource '*',
headers: :any,
methods: %i[get post put patch delete options head]
end
end
Next.js側の設定
環境変数の設定
先ほどRailsの.envに記載した下記の内容をNext.jsの環境変数にも書いて対応させます。
AUTH0_IDENTIFIER=xxxxxxx
Next.js側の追記事項
NEXT_PUBLIC_BASE_URL='http://localhost:9000'
NEXT_PUBLIC_AUTH0_DOMAIN='xxxxxx'
NEXT_PUBLIC_AUTH0_CLIENT_ID='xxxxxx'
NEXT_APP_REST_URL="http://localhost:3000/api/v1"
NEXT_PUBLIC_AUTH0_AUDIENCE="xxxxx" // ここにAUTH0_IDENTIFIEの値を入れる
_appで環境変数を読み取る
import "../styles/globals.css";
import { Auth0Provider } from "@auth0/auth0-react";
function MyApp({ Component, pageProps }) {
//ログイン後のリダイレクト先を指定
const redirectUri = `${process.env["NEXT_PUBLIC_BASE_URL"]}/login`;
return (
<Auth0Provider
domain={process.env["NEXT_PUBLIC_AUTH0_DOMAIN"]!}
clientId={process.env["NEXT_PUBLIC_AUTH0_CLIENT_ID"]!}
audience={process.env["NEXT_PUBLIC_AUTH0_AUDIENCE"]!} // 追記
redirectUri={redirectUri}
>
<Component {...pageProps} />
</Auth0Provider>
);
}
export default MyApp;
これでNext.js側でログイン後に取得できるToKenを利用して、Rails側のアプリでも認証をすることができるようになりました。
aixosのインストール
API通信はaxios
を利用して行うのでインストールをする
npm install axios --save
Recoilの導入
今回はグローバルState(Recoil)でAuth0から取得できるTokenを管理します。
フロント側は以下の流れで処理を行います。
- Auth0経由でログイン処理
- ログイン後にリダイレクトするページでTokenを取得しRecoilへ格納
- ブログ投稿ページへ遷移しRecoilからTokenを取得
- 取得したTokenを使ってRails側に新規投稿のリクエストを送る
なおRecoilについての詳しい解説はここでは割愛するので、気になった方はこちらの記事を参考にしてみてください。
さっそくRecoilをインストールしていきます。
npm install recoil
RecoilRoot
でアプリをラップする。
import "../styles/globals.css";
import { Auth0Provider } from "@auth0/auth0-react";
import { RecoilRoot } from "recoil";
function MyApp({ Component, pageProps }) {
//ログイン後のリダイレクト先を指定
const redirectUri = `${process.env["NEXT_PUBLIC_BASE_URL"]}/login`;
return (
<Auth0Provider
domain={process.env["NEXT_PUBLIC_AUTH0_DOMAIN"]!}
clientId={process.env["NEXT_PUBLIC_AUTH0_CLIENT_ID"]!}
audience={process.env["NEXT_PUBLIC_AUTH0_AUDIENCE"]!}
redirectUri={redirectUri}
>
<RecoilRoot>
<Component {...pageProps} />
</RecoilRoot>
</Auth0Provider>
);
}
export default MyApp;
次にRecoilで使うatoms
の設定を行います。
import { atom } from "recoil";
const tokenState = atom({
key: "tokenState",
default: "",
});
export default tokenState;
ログイン後にトークンを取得しRecoilに格納する
Auth0側でログイン完了後にリダイレクトされるページでTokneを取得しRecoilに格納します。
import { useAuth0 } from "@auth0/auth0-react";
import { NextPage } from "next";
import { useRouter } from "next/router";
import React, { useEffect } from "react";
// recoil
import { useSetRecoilState } from "recoil";
import tokenState from "../recoil/atoms/tokenState";
const LoginPage: NextPage = () => {
const router = useRouter();
const { isAuthenticated, logout, getAccessTokenSilently } = useAuth0();
const setToken = useSetRecoilState(tokenState);
// ログイン完了後にトークンを取得しRecoilへ格納
useEffect(() => {
const getToken = async () => {
try {
const accessToken = await getAccessTokenSilently({});
setToken(accessToken);
} catch (e) {
console.log(e.message);
}
};
getToken();
}, []);
return (
<div>
<h2>ログイン状態</h2>
{isAuthenticated ? (
<>
<p>ログイン中です</p>
<button onClick={() => logout({ returnTo: window.location.origin })}>
ログアウト
</button>
<button
onClick={() => {
router.push("/blog");
}}
>
記事投稿ページへ
</button>
</>
) : (
<p>ログアウトしています</p>
)}
</div>
);
};
export default LoginPage;
-
useAuth0()
のgetAccessTokenSilently
を利用してTokenを取得する -
useSetRecoilState(tokenState)
でRecoilのTokenを更新する -
useEffect
内でレンダリング時に処理が走るようにする - また
useRouter()
でblogページへ遷移する導線を作成
ブログページでReocilからTokneを取得する
遷移したblogページでRecoilからTokneを取得できるか確認します。
import { NextPage } from "next";
import React from "react";
// recoil
import { useRecoilValue } from "recoil";
import tokenState from "../recoil/atoms/tokenState";
const BlogPage: NextPage = () => {
const token = useRecoilValue(tokenState); // RecoilのTokneを取得する
console.log(token);
return <div>ブログ投稿</div>;
};
export default BlogPage;
ブラウザを確認するとconsoleでトークンが表示されていることが確認できるかと思います。
GETメソットでブログデータを取得する
まずはTokneを付与せずに実行できるGETメソットを使ってブログ記事が取得できるかを試してみます。
import axios from "axios";
import { NextPage } from "next";
import React, { useEffect } from "react";
// recoil
import { useRecoilValue } from "recoil";
import tokenState from "../recoil/atoms/tokenState";
const BlogPage: NextPage = () => {
const token = useRecoilValue(tokenState);
useEffect(() => {
const getPosts = async () => {
const res = await axios.get("http://localhost:3000/api/v1/posts");
console.log(res);
};
getPosts();
});
return <div>ブログ投稿</div>;
};
export default BlogPage;
ブラウザで確認するとデータが取得できていることが確認できます。
Tokneを付与してPOSTメソットを実行する
次はReocilのTokneをリクエストヘッダーに付与し記事を新規作成します。
まずはタイトルと説明を入力するフォームとstateを追加します。
確認ようなのでスタイルは特に当てていないです。
import { useAuth0 } from "@auth0/auth0-react";
import axios from "axios";
import { NextPage } from "next";
import React, { useEffect, useState } from "react";
// recoil
import { useRecoilValue } from "recoil";
import tokenState from "../recoil/atoms/tokenState";
const BlogPage: NextPage = () => {
const token = useRecoilValue(tokenState);
const [title, setTitle] = useState<string>("");
const [caption, setCaption] = useState<string>("");
const onChange = (
e: React.ChangeEvent<HTMLInputElement>,
setState: React.Dispatch<React.SetStateAction<string>>
) => {
setState(e.target.value);
};
return (
<div>
<label htmlFor="">タイトル</label>
<input
type="text"
value={title}
onChange={(e) => {
onChange(e, setTitle);
}}
/>
<br />
<label htmlFor="">本文</label>
<input
type="text"
value={caption}
onChange={(e) => {
onChange(e, setCaption);
}}
/>
<br />
<button>新規投稿</button>
</div>
);
};
export default BlogPage;
次に入力されたデータをパラメタと送信するための新規登録用のAPIコールメソットを作成します。
import { useAuth0 } from "@auth0/auth0-react";
import axios from "axios";
import { NextPage } from "next";
import React, { useEffect, useState } from "react";
// recoil
import { useRecoilValue } from "recoil";
import tokenState from "../recoil/atoms/tokenState";
const BlogPage: NextPage = () => {
const token = useRecoilValue(tokenState);
const [title, setTitle] = useState<string>("");
const [caption, setCaption] = useState<string>("");
const onClick = () => {
const params = {
title: title,
caption: caption,
};
console.log(token);
axios
.post("http://127.0.0.1:3000/api/v1/posts", params, {
headers: {
Authorization: `Bearer ${token}`,
},
})
.then((res) => {
console.log(res);
})
.catch((error) => {
console.log(error);
});
};
const onChange = (
e: React.ChangeEvent<HTMLInputElement>,
setState: React.Dispatch<React.SetStateAction<string>>
) => {
setState(e.target.value);
};
return (
<div>
<label htmlFor="">タイトル</label>
<input
type="text"
value={title}
onChange={(e) => {
onChange(e, setTitle);
}}
/>
<br />
<label htmlFor="">本文</label>
<input
type="text"
value={caption}
onChange={(e) => {
onChange(e, setCaption);
}}
/>
<br />
<button onClick={onClick}>新規投稿</button>
</div>
);
};
export default BlogPage;
- axiosの
headers
の中にRecoilに保存されていたTokenを入れる -
params
にtitleとcaptionの値を入れる - 登録後の成功を確認するために
res
をconsole
で表示させる
実際に値を入れて新規登録ボタンを押してみます
consoleを確認すると成功のレスポンスが確認できます。
Tokneをの値を空にして同様の処理を行うとNot Authenticated
のレスポンスが返ってきます。
最後に
いかがだったでしょうか。
今回はAuth0を利用してNext.js×RailsのSPA構成で認証機能の実装を行いました。
Auth0はドキュメントも豊富かつチュートリアルもあるのでサクッと導入することができるので、ぜひ今後の認証機能周りの開発の際に使っていただければと思います。
他にも記事を出しているので、併せて読んでいただけると嬉しいです。