Newer
Older
mobile.raikyakun.app / node / src / app / accessKey / route.ts
nutrition 14 hours ago 1 KB 利便性向上
import { NextResponse } from 'next/server'
import { cookies } from 'next/headers'

const COOKIE_NAME = '__Host-raikyakun_access'
const COOKIE_MAX_AGE = 60 * 60 * 24 * 400

export async function GET() {
	const cookieStore = await cookies()
	const accessKey = cookieStore.get(COOKIE_NAME)?.value ?? null

	const res = NextResponse.json({ accessKey })
	res.headers.set('Cache-Control', 'no-store')

	if (accessKey) {
		// Rolling: アクセスのたびに期限をリセット
		res.cookies.set(COOKIE_NAME, accessKey, {
			httpOnly: true,
			secure: true,
			sameSite: 'lax',
			path: '/',
			maxAge: COOKIE_MAX_AGE,
		})
	}

	return res
}

export async function DELETE() {
	const res = new NextResponse(null, { status: 204 })
	res.cookies.set(COOKIE_NAME, '', {
		httpOnly: true,
		secure: true,
		sameSite: 'lax',
		path: '/',
		maxAge: 0,
	})
	return res
}

export async function POST(req: Request) {
	// ざっくりCSRF対策:同一オリジン以外を弾く(不要なら削除OK)
	const origin = req.headers.get('origin') ?? ''
	const host = req.headers.get('host') ?? ''
	if (origin && host && !origin.includes(host)) {
		return new NextResponse('forbidden', { status: 403 })
	}

	const { accessKey } = await req.json().catch(() => ({} as any))
	if (typeof accessKey !== 'string' || accessKey.length === 0) {
		return new NextResponse('bad request', { status: 400 })
	}

	const res = NextResponse.json({ ok: true })
	res.headers.set('Cache-Control', 'no-store')
	res.headers.set('Referrer-Policy', 'no-referrer')

	res.cookies.set('__Host-raikyakun_access', accessKey, {
		httpOnly: true,
		secure: true,      // HTTPS必須(ローカルHTTPなら開発時だけfalseに)
		sameSite: 'lax',
		path: '/',
		maxAge: COOKIE_MAX_AGE,
	})

	return res
}