はじめに
Cognitoのマネージドログインをnext.jsで実装してみました。next.js初心者なのであまり自信ないですが、参考になれば幸いです。実際のCognitoと連携できるかは確認できていないソースなので注意です。
ソース
page.tsx
"use client";
import { useAuth } from "react-oidc-context";
function Page() {
const auth = useAuth();
console.log("page.tsx起動");
const signOutRedirect = () => {
const clientId = "YOUR_COGNITO_CLIENT_ID";
const logoutUri = "http://localhost:3000";
const cognitoDomain = "YOUR_COGNITO_DOMAIN";
window.location.href = `${cognitoDomain}/logout?client_id=${clientId}&logout_uri=${encodeURIComponent(
logoutUri
)}`;
};
if (auth.isLoading) {
return <div>Loading...</div>;
}
if (auth.error) {
return <div>Error: {auth.error.message}</div>;
}
if (auth.isAuthenticated) {
return (
<div>
<p>Hello: {auth.user?.profile.email}</p>
<button onClick={() => auth.removeUser()}>Sign out</button>
</div>
);
}
return (
<div>
<button onClick={() => auth.signinRedirect()}>Sign in</button>
<button onClick={signOutRedirect}>Sign out</button>
</div>
);
}
export default Page;
AuthProviderWrapper.tsx
"use client";
import React from "react";
import { AuthProvider } from "react-oidc-context";
// layout.tsxでMetadataを使用するためには"use client";を書いてはいけない
// AuthProviderを使用するためには"use client";が必要
// →AuthProviderを別コンポーネントに分離
export default function AuthProviderWrapper({
children,
}: {
children: React.ReactNode;
}) {
console.log("AuthProviderWrapper.tsx起動");
const oidcConfig = {
authority: "~",
client_id: "~",
redirect_uri: "~",
response_type: "~",
scope: "~",
extraQueryParams: {
ui_locales: "ja",
},
};
return <AuthProvider {...oidcConfig}>{children}</AuthProvider>;
}
layout.tsx
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import AuthProviderWrapper from "./AuthProviderWrapper";
import "./globals.css";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
console.log("layout.tsx起動");
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
<AuthProviderWrapper>{children}</AuthProviderWrapper>
</body>
</html>
);
}
おわりに
TypeScript、React、next.jsもっと勉強が必要そうです。