NextAuthを使ったDiscord認証
NextAuthを利用することで簡単にDiscord認証を実装できるので、その紹介になります。
基本的には公式ドキュメントを参考にしていますので、詳しくはそちらをご覧ください。
今回使っているnext-authのバージョンは、"next-auth": "^5.0.0-beta.19" です。
Discord Developer側の準備
後でCLIENT ID, CLIENT SECRETを使いますのでメモしておきましょう。
Next.js側での処理
Authの基本的な書き方は下記の動画を参考にしましたので、詳しくはそちらをどうぞ。
https://www.youtube.com/watch?v=2xexm8VXwj8
.env
// example-project/.env
AUTH_SECRET = ******
AUTH_URL=http://localhost:3000/api/auth
AUTH_DISCORD_ID = 先ほど取得したID
AUTH_DISCORD_SECRET = 先ほど取得したSECRET
auth.ts
// example-project/auth.ts
import NextAuth from "next-auth";
import Discord from "next-auth/providers/discord"
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [Discord({
clientId: process.env.AUTH_DISCORD_ID as string,
clientSecret: process.env.AUTH_DISCORD_SECRET as string
})],
basePath: "/api/auth",
callbacks: {
authorized({request, auth}){
try{
const {pathname} = request.nextUrl;
if(pathname === "/protected-pge") return !!auth;
return true;
} catch(err) {
console.log(err);
}
},
jwt({ token, trigger, session, account}) {
if(account){
// 初回の認証時に実行
token.id = account.providerAccountId
}
if(trigger === "update") token.name = session.name;
return token;
},
session({ session, user, token }) {
session.user.id = token.id as string
return session
},
},
session: {
// sesstionTime (second)
maxAge: 600
}
})
serverAction.ts
// example-project/app/serverActions/serverAction.ts
"use server";
import { signIn } from '@/auth';
export async function handleSignin() {
await signIn("discord");
}
// example-project/app/compose/SigninButton/SigninButton.tsx
import React from 'react'
import { handleSignin } from '../../serverActions/serverAction';
export default async function SigninButton() {
return(
<form action={handleSignin}>
<button type='submit'>
Signin
</button>
</form>
);
}
// example-project/app/compose/UserButton/UserButton.tsx
import React from 'react'
import { auth } from "@/auth";
import SigninButton from "../SigninButton/SigninButton";
import layout from "./userButton.module.scss";
export default async function UserButton() {
const session = await auth();
let imgPath = "https://upload.wikimedia.org/wikipedia/commons/2/2e/Microsoft_Account_Logo.svg"
//sesstionが無ければsigninを表示
if(! session?.user) return <div><SigninButton/><img className={layout.userAccountImg} src={imgPath} /></div>;
imgPath = session.user.image as string
return(
<div>
<img className={layout.userAccountImg} src={imgPath} />
<pre>
{JSON.stringify(session, null, 2)}
</pre><br />
</div>
);
}
route.ts
// example-project/app/api/auth/[...nextauth]/route.ts
import { handlers } from "@/auth";
export const { GET, POST } = handlers;
middleware.ts
// example-project/middleware.ts
export {auth as middleware } from "@/auth";
export const config = {
// matcher: "/profile:",
};
認証時の実行結果
最後に
今回の紹介したコードに加えたプロジェクトをgithubに公開していますので、参考までにどうぞ。