Open6
next-auth@5.0.0(Auth.js) メモ
strategy
- ユーザセッションの保存方法
- デフォルトでは
jwt
になり、Cookieに保存される - アダプタ(データベース)を使用する場合は、
database
になる- ただし、明示的に
jwt
と定義することで、jwtセッションを強制できる
- ただし、明示的に
auth.ts
// データベースを使用し、jwtも使用する場合
export const { handlers, signIn, signOut, auth } = NextAuth({
...authConfig,
adapter: PrismaAdapter(prisma),
session: {strategy: "jwt"},
callbacks: {
session: ({token, session, user}) => {
return {
...session,
user: {
...session.user,
id: token.sub
}
}
}
}
});
OAuthを使用する場合デフォルトで取れる認証情報は以下のものである。
- name
- image
これだけだと不十分なので、今回はSession callbackの中でuser.idにユーザーIDであるtoken.subを追加している。
jwt callback
ここでreturnされるものはすべてJWTに保存され、session callbackに転送される。
引数のuser
、account
、profile
はサインイン時のみ渡される。
auth.ts
callbacks: {
async jwt({ token, user, account, trigger, session }) {
// サインイン時
if (user) {
token.name = user.name;
}
// セッション更新時の処理
if (trigger == "update" && session?.name) {
console.log("-- セッション更新 --")
token.name = session.name;
token.isNewUser = false; // 名前が設定されたらNewUserをfalseに
}
return token;
},
Prismaを使用する場合、引数のuser
の中身はschema.prisma
によって決まる
account
はほぼスキーマ通りだったが違う部分も見られた。
user
"user": {
"id": "xxxxxxxxxxxxxxxxxxxxxxx",
"name": "atnuhs",
"email": "xxxxxxxxxx@gmail.com",
"emailVerified": null,
"image": "https://xxxxxxxxxxxxxxxxxxxxxxxxx"
},
token
token: {
name: 'atnuhs',
email: 'xxxxxxxxxx@gmail.com',
picture: 'https://xxxxxxxxxxxxx',
sub: 'xxxxxxxxxxxxx' // user.idと一緒
}
account
account: {
access_token: 'xxxxxxxxxxxxx',
expires_in: 3599,
scope: 'https://www.googleapis.com/auth/userinfo.profile openid https://www.googleapis.com/auth/userinfo.email',
token_type: 'bearer',
id_token: 'xxxxxxxxxxxxx',
expires_at: 1728144477,
provider: 'google',
type: 'oidc',
providerAccountId: 'xxxxxxxxxxxxxxxxxxxx'
}
profile
"profile": {
"iss": "https://accounts.google.com",
"azp": "xxxxxxxxxxx",
"aud": "xxxxxxxxxxxxxx",
"sub": "xxxxxxxxxxxx",
"email": "xxxxxxxx@gmail.com",
"email_verified": true,
"at_hash": "xxxxxxx",
"name": "atnuhs",
"picture": "https://xxxxxxxx",
"given_name": "atnuhs",
"iat": 1728123231,
"exp": 1728126831
},
session callback
sessionがチェックされるたびに呼び出される。
-
const session = auth()
を呼び出したときにsession
に入る値を決める。 -
token
引数はjwt session strategyを使用しているとき、user
引数はdatabase session strategyを使用しているときのみ使用可能。(例:jwt strategyを使用しているときはuser
引数はundefined
になる) -
token
引数はjwt callbackでtoken
に追加したものが入る。 -
user
引数はDBに保存されたUser
データが入る。
以下はsessionにuserIdを追加する例:
auth.ts
callbacks: {
session: ({ token, session, user }) => {
return {
...session,
user: {
...session.user,
id: token.sub,
},
};
},
},
unstable_update
サーバーサイドでSessionを更新する方法?
ローカルと本番環境でcookieNameが違う
後で見る
middleware.tsのtokenの取得でcookieNameを指定するところを本番環境とローカルで条件分岐させたい
ローカルとvercelの環境変数にTOKEN_COOKIE_NAMEを設定して対応した
型定義の拡張について
- "next-auth"のUserがjwt callbackのuserの定義
- "next-auth/jwt"のJWTがjwt callbackとsession callbackのtokenの定義
- ※AdapterUserの拡張は必要だった気がしたけど、なくてもいけたので要調査
- わかんなくなったときは
auth.ts
で引数をホバーしたらわかると思う
next-auth.d.ts
import { UserRole } from "@prisma/client";
import NextAuth, {type DefaultSession } from "next-auth"
declare module "next-auth" {
interface Session {
user: {
id: string;
isProfileComplete: boolean; // 追加
role: UserRole; // 追加
} & DefaultSession['user'];
}
// jwt callbackのuser
interface User {
id: string;
name: string;
email: string;
emailVerified: boolean;
image: string;
isProfileComplete: boolean; // 追加
role: UserRole; // 追加
}
}
declare module "next-auth/jwt" {
// jwt callbackとsession callbackのtoken
interface JWT {
role: UserRole; // 追加
isProfileComplete: boolean; // 追加
}
}
declare module "@auth/core/adapters" {
interface AdapterUser extends User {
isProfileComplete: boolean; // 追加
role: UserRole; // 追加
}
}