사용자가 로그인을 완료 하면Authorization Server가 파라미터의redirect_url로 authorization code를 포함하여 리다이렉팅 시키며 NextAuth는client_id,client_secret,redirect_url및 받아온authorization code값을 파라미터로하여AccessToken을 포함한 여러 계정정보를 받아온다. 이때 NextAuth에서 관리하는 Model중 하나인User Model에 OAuth Profile (id, name, email, image) 정보가 저장되며 이는 Provider의 Profile 콜백을 통하여 확장할 수 있다. 또한Account Model에는 OAuth 계정에 관한 정보가 저장되며 일반적으로 리소스 서버에 요청을할때 필요한AccessToken도 이에 포함된다.
그런다음 NextAuth 옵션 객체의callbacks의 메소드들이 실행되며 이때 클라이언트 사이드 쪽에서useSession을 통해 토큰의 정보 및 유저 정보를 가져가게 할 수 있게 하기 위해서 초기로그인시 필요한 정보를 담아 NextAuth 내의 jwt 토큰을 만들어주고 세션에도 필요한 정보를 넘길 수 있다. 주의할점은 jwt메서드의 token은 Authorization Server에서 받아온 토큰을 뜻하는것이 아니라는것이다. jwt메서드의 token은 NextAuth의 Account Models과 User Models를 정보를 조합하여 NextAuth에서 유지하는 토큰이다. Models에 관한 정보는NextAuth 공식문서에서 볼 수 있다.
jwt calback
웹 토큰이 실행 또는 업데이트될때마다 콜백이 실행된다.반환된 값은 암호화 되어 쿠키에 저장된다.
import { NextAuthOptions, User } from "next-auth";
import GoogleProvider from "next-auth/providers/google";
export const options: NextAuthOptions = {
providers: [ ... ],
callbacks: {
async jwt({ token, user, account}) {
// 초기 로그인시 User 정보를 가공하여 반환
if (account && user) {
return {
accessToken: account.access_token,
accessTokenExpires: account.expires_at,
refreshToken: account.refresh_token,
user,
};
}
return token;
},
},
};
session callback
클라이언트 사이드에서 useSession을 사용했을때 확인할 수 있는 session 값에 대한 콜백이다.
typescript에서 이를 확장하기 위해선 최상위 디렉토리에서 next_auth.d.ts파일을 만들어 기본 세션 interface를 확장하여 사용할 수 있다.
import { NextAuthOptions, User } from "next-auth";
import GoogleProvider from "next-auth/providers/google";
export const options: NextAuthOptions = {
providers: [ ... ],
callbacks: {
...
async session({ session, token }) {
session.user = token.user as User;
session.accessToken = token.accessToken as string;
session.accessTokenExpires = token.accessTokenExpires as string;
session.error = token.error;
return session;
},
},
};
next_auth 공식 문서에서 친절하게 access_token을 refresh 하는 샘플 코드를 제공해준다. 하지만 이 방법은 access_token이 만료된 후에 권한이 끊기고 난 후에 refresh 하는 방법이다. 좀 더 매끄러운 권한 연장을 위해서 참고한 블로그 글과 공식문서를 합쳐서 아래와 같이 구성했다.