목차
next-auth session을 사용하다보면 session에 값을 추가하고 싶을 때가 있다.
예를 들어 user의 role을 추가 하고 싶으면 어떻게 해야 될까?
next-auth session에 정보 추가
src/auth.ts
import NextAuth from 'next-auth';
import KakaoProvider from 'next-auth/providers/kakao';
import { cookies } from 'next/headers';
export const {
handlers: { GET, POST },
auth,
} = NextAuth({
providers: [
KakaoProvider({
clientId: process.env.AUTH_KAKAO_CLIENT_ID!,
clientSecret: process.env.AUTH_KAKAO_CLIENT_SECRET!,
async profile(profile) {
const name = profile.kakao_account?.profile?.nickname;
const email = profile.kakao_account?.email;
const image = profile.kakao_account?.profile?.profile_image_url;
const response = await fetch('http://localhost:8000/auth/login', {
method: 'POST',
body: JSON.stringify({
name,
email,
image,
}),
headers: {
'Content-Type': 'application/json',
},
});
const data = await response.json();
if (data) {
const { accessToken, refreshToken } = data;
// 브라우저에 쿠키를 심어주는 것
cookies().set('accessToken', accessToken);
cookies().set('refreshToken', refreshToken);
}
return {
id: String(profile.id),
name,
email,
image,
role: data.role,
};
},
}),
],
});
KakaoProvider에는 profile 콜백이 있다.
기본적으로 ID, 이름, 이메일, 사진을 반환하지만 더 많은 정보를 반환할 수도 있다.
profile 콜백에 있는 profile 매개변수는 카카오에서 제공하는 모든 정보를 볼 수 있다.
여기서 필요한 것만 추출해 낸다면 위 코드와 같이 할 수 있다.
더 추가하고 싶은 정보가 있으면 return에다가 값을 넣으면 된다.
하지만 여기서 끝이 아니다.
src/auth.ts
import NextAuth from 'next-auth';
import KakaoProvider from 'next-auth/providers/kakao';
import { cookies } from 'next/headers';
export const {
handlers: { GET, POST },
auth,
} = NextAuth({
providers: [
// 위 코드와 동일
],
callbacks: {
async jwt({ token, user }) {
return { ...token, ...user };
},
async session({ session, token }) {
if (session.user && token.role) {
session.user.role = token.role;
}
return session;
},
},
});
위 커스텀한 유저의 정보가 callbacks의 jwt 함수 user 라는 매개변수에 담기게 된다.
console로 user 정보를 찍어보면 role 값이 추가 된 것을 볼 수 있다. (로그인시에만 값이 찍히는데 왜그런지는 모르겠다.)
jwt 함수는 기본적으로 token을 반환해야 한다. 그래서 user 매개변수와 token 매개변수를 구조분해하여 합쳐준다.
jwt에서 리턴하는 값은 session 함수의 token 값으로 전달되게 된다.
이제서야 session 값에 role이라는 변수를 추가하여 session을 리턴하면 커스텀한 session을 만들 수 있다.
session type 에러 해결
만약 타입스크립트로 위 코드를 따라했을 경우 아래와 같은 타입 에러가 뜬다. (next-auth의 session에서 정의한 타입과 달라서 뜨는 에러이다. 위 에러를 해결하기 위해서는 session 타입을 수정해줘야 한다.)
src/types/next-auth.d.ts
import NextAuth, { type DefaultSession } from 'next-auth';
declare module 'next-auth' {
interface Session {
user: {
role: 'admin' | 'user';
} & DefaultSession['user'];
}
}
import { JWT } from '@auth/core/jwt';
declare module '@auth/core/jwt' {
interface JWT {
role: 'admin' | 'user';
}
}
결과
관리자만 들어갈 수 있는 페이지 만들기
src/app/admin/page.tsx
export default function Adminpage() {
return <div>Adminpage</div>;
}
src/middleware.ts
import { auth } from './auth';
import { NextRequest, NextResponse } from 'next/server';
export async function middleware(request: NextRequest) {
const session = await auth();
if (request.nextUrl.pathname.startsWith('/mypage')) {
if (!session) {
return NextResponse.redirect(new URL('/login', request.url));
}
}
if (request.nextUrl.pathname.startsWith('/admin')) {
if (session?.user.role !== 'admin') {
return NextResponse.redirect(new URL('/', request.url));
}
}
}
export const config = {
matcher: ['/mypage/:path*', '/admin/:path*'],
};
참고 문서
https://authjs.dev/guides/providers/custom-provider#override-default-provider-config
https://authjs.dev/guides/basics/callbacks#jwt-callback
https://authjs.dev/getting-started/typescript
https://nextjs.org/docs/app/building-your-application/routing/middleware
전체 코드
https://github.com/msm0748/next-auth-5-study
반응형
'Project > 코하루 마켓' 카테고리의 다른 글
Next-auth v5 데이터베이스에 유저 정보 추가 - NestJS (4) | 2023.12.28 |
---|---|
Next-auth v5 카카오 로그인 구현 (0) | 2023.12.22 |
Nextjs 공통 레이아웃 만들기 (0) | 2023.12.12 |