pauth.me × Next.js — 着信認証API実装ガイド
Next.js(TypeScript)プロジェクトにpAuth着信認証APIを組み込む手順を解説します。 API Routesでサーバーサイド処理を行い、フロントエンドからポーリングで認証完了を確認します。
※本ページのコード例は説明目的の擬似コードです。実際の実装では環境に合わせた調整が必要です。
前提条件
- Node.js 18以上 / Next.js 13以上(App Router または Pages Router)
- pauth.me APIキー(無料登録で取得)
Step 1: 環境変数の設定
# .env.local
PAUTH_API_KEY=your_api_key_here
PAUTH_BASE_URL=https://api.pauth.me
Step 2: API Route — 認証セッション開始
// pages/api/auth/start.ts
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== 'POST') return res.status(405).end()
const { phoneNumber } = req.body
const response = await fetch(`${process.env.PAUTH_BASE_URL}/v1/auth/sessions`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PAUTH_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
phone_number: phoneNumber,
callback_url: `${process.env.NEXT_PUBLIC_BASE_URL}/api/auth/callback`,
}),
})
const data = await response.json()
res.json({ sessionId: data.id, callNumber: data.call_number })
}
Step 3: フロントエンド — ポーリングで認証確認
// components/PhoneAuth.tsx
import { useState, useEffect } from 'react'
export function PhoneAuth({ sessionId }: { sessionId: string }) {
const [status, setStatus] = useState<'pending' | 'verified' | 'expired'>('pending')
useEffect(() => {
if (status !== 'pending') return
const timer = setInterval(async () => {
const res = await fetch(`/api/auth/status?sessionId=${sessionId}`)
const data = await res.json()
if (data.status === 'verified') {
setStatus('verified')
clearInterval(timer)
// ログイン処理へ
} else if (data.status === 'expired') {
setStatus('expired')
clearInterval(timer)
}
}, 2000) // 2秒ごとにポーリング
return () => clearInterval(timer)
}, [sessionId, status])
return (
<div>
{status === 'pending' && <p>電話をかけて認証を完了してください…</p>}
{status === 'verified' && <p>認証完了!</p>}
{status === 'expired' && <p>タイムアウトしました。再試行してください。</p>}
</div>
)
}
エラーハンドリング
// API Routeでのエラー処理
if (!response.ok) {
const error = await response.json()
return res.status(response.status).json({ error: error.message })
}
// フロントエンドでの最大試行回数制限
const MAX_POLLS = 30 // 60秒でタイムアウト
let pollCount = 0
const timer = setInterval(async () => {
if (++pollCount > MAX_POLLS) {
setStatus('expired')
clearInterval(timer)
}
// ...ポーリング処理
}, 2000)
本番環境の注意点
- APIキーはサーバーサイド(API Routes)のみで使用し、クライアントに公開しない
NEXT_PUBLIC_プレフィックスをAPIキーに付けない- セッションIDをサーバーサイドセッション(NextAuth.js等)で管理する
- App Routerの場合は Server Actions または Route Handlers を使用する