저번 시간에는 NextAuth
를 이용한 로그인 구현 방식에 대해서 알아보았는데, 어제 방식을 이용하면 서버에서 session
을 이용해서 꺼낼 수 있는 데이터는 email
, name
, image
3가지가 끝이다.
하지만 사용자마다 session
에 저장하고 싶은 데이터가 있을텐데 어떻게 session
에 데이터를 저장할 수 있는지를 Callbacks
를 이용해서 살펴볼 예정이다.
보다 더 많은 정보를 확인하고 싶으면 아래의 공식 문서 참고
그럼 저번 포스팅의 코드에서 이어서 진행하도록 하겠습니다.
일단 [...nextauth].ts
파일을 열고 callbacks
를 사용할 준비를 다음과 같이 한다.
import NextAuth from "next-auth"
import Providers from "next-auth/providers"
import {NextApiRequest} from "next";
export default NextAuth({
providers: [
Providers.Credentials({
// 생략
async authorize(credentials: Record<any, any>, req: NextApiRequest) {
const email = credentials.email;
const password = credentials.password;
if (email === "test@test.com" && password === "test") {
return credentials;
}
throw new Error("아이디 혹은 패스워드가 틀립니다.");
}
})
],
pages: {
signIn: '/login',
},
// 아래 부분 추가
callbacks: {
async jwt(token, user, account, profile, isNewUser) {
return token;
},
async session(session, userOrToken) {
return session
}
}
})
공식문서를 보면 다음과 같이 작성되어있다.
If you want to pass data such as an Access Token or User ID to the browser when using JSON Web Tokens, you can persist the data in the token when the jwt callback is called, then pass the data through to the browser in the session callback.
간략하게 요약하면 무언가 데이터를 넘겨주고 싶으면 jwt
토큰에 데이터를 유지하고 session
에서 처리해주면 된다는 내용이다.
따라서 우리가 callbacks
에서 이용할 함수는 jwt
와 session
이다.
먼저, 로그인 이벤트가 발생하면 다음의 흐름으로 데이터가 흘러간다.
providers
내부의async authorize
에 인증을 실행callbacks
의jwt
함수가 실행callbacks
의session
함수가 실행
따라서 로그인 인증이 성공하면 jwt
함수에서 토큰이 생성되고 해당 토큰을 기반으로 session
이 생성되게 된다. 그럼 바로 코드를 작성해보도록 하자.
callbacks: {
async jwt(token, user, account, profile, isNewUser) {
token.userId = 123;
token.test = "test";
return token;
},
async session(session: any, userOrToken: any) {
session.user.userId = userOrToken.userId;
session.user.test = userOrToken.test;
return session
}
}
위의 코드를 설명하면 다음과 같다.
token
정보에다가 내가 커스텀으로 넣어주고 싶은 데이터를 다음과 같이 넣어준다.
token.userId = 123;
token.test = "test;
{
... 생략
userId: 123,
test: 'test'
}
그러고 token
을 콘솔찍어보면 위와 같이 userId
와 test
키 값으로 데이터가 들어간 모습을 확인할 수 있다.
그리도 async session
함수에서 userOrToken
파라미터로 토큰 정보를 받을 수 있고 다음과 같이 session
에 데이터를 넣어준다.
session.user.userId = userOrToken.userId;
session.user.test = userOrToken.test;
그러면 최종적으로 session
데이터를 콘솔로 찍어보면 다음과 같이 데이터를 확인할 수 있다.
{
name: null,
email: 'test@test.com',
image: null,
userId: 123,
test: 'test'
}
따라서 앞으로 서버에서 getSession
함수를 이용해서 데이터를 꺼내서 사용할 수 있는 폭이 userId
와 test
로 늘어났다고 할 수 있다.
추가로 login.tsx
파일에서 signIn
함수안에 callbackUrl
을 설정해주고 로그인이 성공했을 때 페이지를 이동시킬 수 있다. 코드는 다음과 같다.
// router에 있는 push 함수를 이용해서 페이지를 전환해줄 수 있다.
const router = useRouter();
const response: any = await signIn("email-password-credential", {
email,
password,
redirect: false,
callbackUrl: "http://localhost:3000/user" // 추가
});
// response이 반환해주는 데이터 중 url이 callbackUrl에 정의된 내용이 들어온다.
// response.url ==> http://localhost:3000/user
await router.push(response.url)
그러면 로그인이 완료되었을 때 자동으로 http://localhost:3000/user 로 이동된다.
저번 시간에 안짚은 부분인 것 같아서 추가하겠습니다!
아마 이정도의 지식만 있어도 NextAuth.js
를 이용해서 로그인 부분을 구현하는데는 큰 지장이 없지 않을까 생각한다. 물론 데이터베이스 연결 부분과 에러 처리 등 안다룬 부분들이 존재하지만 그 부분들은 개발 하시면서 크게 어려운 부분은 아니라고 생각해서 제외하였습니다.
혹시라도 알고 싶으시다면 댓글 달아주시고, 최대한 안내해드리도록 하겠습니다.
그럼 이만 총총..
글 잘읽었습니다. 정말 큰 도움이 됬어요.
생각보가 지원되고 이미 구현되어 있는 Provider가 많아서 활용도가 높겠네요. 지금 v4 와 코드 차이가 약간 있어 해멨 지만 금방 적응할수 있었습니다.
감사합니다.