generated from amazon-archives/__template_MIT-0
-
Notifications
You must be signed in to change notification settings - Fork 38
Closed
Labels
bugSomething isn't workingSomething isn't workingenhancementNew feature or requestNew feature or request
Milestone
Description
問題
現在の auth.ts と認証関連コンポーネントに以下の問題がある。
1. 認証APIルートへの <Link> 使用によるCORSエラーの可能性
Header.tsx と sign-in/page.tsx で認証APIルート(/api/auth/sign-out, /api/auth/sign-in)に <Link prefetch={false}> を使用している。
prefetch={false} はプリフェッチを無効にするが、クリック時のクライアントサイドナビゲーション(RSCペイロードのfetch)は発動する。認証APIルートはCognitoへの302リダイレクトを返すため、fetchがクロスオリジンのCognitoドメインを追跡し、CORSエラーが発生しうる。
// 現在
<Link href="/api/auth/sign-out" prefetch={false}>Sign Out</Link>
// 修正: 通常のブラウザナビゲーションで302リダイレクトを正しく処理
<a href="/api/auth/sign-out">Sign Out</a>sign-in/page.tsx も同様に <a> タグに変更する。
2. getSession() がトークン期限切れ時に例外を投げ、認証エラーとサーバーエラーを区別できない
現在の getSession() は認証セッション取得とDBアクセスが一体化しており:
- トークン期限切れ時に例外が投げられ、呼び出し側で認証エラー(401相当)とサーバーエラー(500相当)を区別できない
- API RouteでuserIdのみ必要な場合でもDBアクセスが発生する
cache()未使用のため、同一リクエスト内で複数回呼ばれると毎回Cognito + DBにアクセスする
以下の3関数に分離することを提案する:
// webapp/src/lib/auth/session.ts
import { cache } from 'react';
import { cookies } from 'next/headers';
import { fetchAuthSession } from 'aws-amplify/auth/server';
import { runWithAmplifyServerContext } from '@/lib/amplifyServerUtils';
import { prisma } from '@/lib/prisma';
// DBアクセスなし。userIdのみ必要な場合
export const getAuthSession = cache(async () => {
const session = await runWithAmplifyServerContext({
nextServerContext: { cookies },
operation: (contextSpec) => fetchAuthSession(contextSpec),
});
if (!session.userSub || !session.tokens?.idToken || !session.tokens?.accessToken) {
throw new Error('session not found');
}
return {
userId: session.userSub,
email: session.tokens.idToken.payload.email as string,
accessToken: session.tokens.accessToken.toString(),
};
});
// 失敗時null返却。API Routeで401を返したい場合
export async function tryGetAuthSession() {
try {
return await getAuthSession();
} catch {
return null;
}
}
// DB + 認証。User情報が必要な場合
export const getSessionWithUser = cache(async () => {
const auth = await getAuthSession();
const user = await prisma.user.findUnique({ where: { id: auth.userId } });
if (!user) throw new Error(`User not found: ${auth.userId}`);
return { ...auth, user };
});3. safe-action.ts の authActionClient も統一すべき
現在の authActionClient は getCurrentUser() で認証しており、auth.ts の getSession() とは別の認証パスになっている。上記の getAuthSession() に統一することで、認証ロジックの重複を解消できる。
検証方法
- トークン期限切れ時にAPI Routeが500ではなく401を返すこと
- DB接続エラー時にサインインリダイレクトしないこと(認証エラーとサーバーエラーの区別)
cache()により同一リクエスト内の重複呼び出しが防止されること- 認証APIルート(
/api/auth/*)が<a>タグで遷移され、CORSエラーが発生しないこと
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingenhancementNew feature or requestNew feature or request