너와 나의 프로그래밍
Next.js - NextAuth.js 본문
Intro🙂
Next.js 프레임워크 환경에서 로그인 기능을 개발하기 위해 여러 가지 방법을 찾아보던 중에 Next.js 공식 Document에 Authentication 부분에서 NextAuth와 With Iron Session의 Providers가 있다고 소개하는 것을 보고 이번에는 NextAuth라는 라이브러리로 로그인 기능을 구현해 봤다.
NextAuth.js?🤔
NextAuth는 Next.js를 위한 쉽게 로그인 기능을 구현하는 것을 도와준다. 일반적인 ID, Password를 통한 로그인부터 JWT, OAuth 등 각종 로그인을 지원한다.
가장 매력적인 것은 지원하고 있는 OAuth들의 종류가 많았다는 점인데, 간단히 구글이나 페이스북, 트위터, 애플 같은 정말 대표적인 소셜 로그인 지원부터 심지어 국내에서 많이 사용하고 있는 카카오, 네이버 로그인까지 지원한다는 점에서 진짜 범용적이고 잘만 사용하면 굉장히 실용적이게 Next.js에서 로그인 기능을 만들 수 있겠구나 싶었다.
이 라이브러리의 가장 큰 장점은 단 몇 분 만에 간단하게 여러 가지 로그인 기능을 쉽게 구현할 수 있는 게 아닐까 싶다. 물론 라이브러리인 만큼 해당 라이브러리의 대한 공부는 꼭 해야 될 것 같다.😂
How to NextAuth.js?🤔
//npm
npm install next-auth
//yarn
yarn add next-auth
npm 명령어나 yarn 명령어를 사용해 next-auth를 설치해 준다.
import { SessionProvider } from "next-auth/react"
export default function App({
Component,
pageProps: { session, ...pageProps },
}) {
return (
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
)
}
pages/_app.jsx(tsx)에 SesisonProvider를 추가해 준다. 이 SessionProvider는 내부적으로 React Context API를 통해 전역적으로 로그인된 Session이 업데이트될 때마다 동기화해 정보를 받을 수 있다.
import { NextPage } from "next";
import { FormEventHandler, useState } from "react";
import { signIn } from "next-auth/react";
const Signin: NextPage = (): JSX.Element => {
const [userInfo, setUserInfo] = useState({
username: "",
password: "",
});
const handleSubmit: FormEventHandler<HTMLFormElement> = async (e) => {
e.preventDefault();
await signIn("credentials", {
email: userInfo.username,
password: userInfo.password,
redirect: false,
}).then((res) => {
if (res?.ok) console.log(res.ok);
});
};
return (
<div>
<form onSubmit={handleSubmit}>
<h1>Login</h1>
<input
type="text"
placeholder="ID"
value={userInfo.username}
onChange={(e) =>
setUserInfo((prev) => ({
...prev,
username: e.target.value,
}))
}
/>
<input
type="password"
placeholder="*******"
value={userInfo.password}
onChange={(e) =>
setUserInfo((prev) => ({
...prev,
password: e.target.value,
}))
}
/>
<input type="submit" value="Login" />
</form>
</div>
);
};
export default Signin;
간단한 로그인 화면을 위해 ID, Password를 입력할 Input 창을 만들어 주고 로그인을 위한 이벤트를 만들어준다.
handleSubmit Function에서 가장 중요한 건 signIn이라는 Hook인데 NextAuth에서 지원하는 Hook으로 로그인을 하기 위한 기본적인 Hook이라고 생각하면 된다. 반대는 signout Hook이 있다.
예제에서는 아이디, 패스워드로만 활용하는 예제라 credentials이라는 옵션을 주었지만 예를 들어 Google이라는 옵션을 통해 구글 로그인을 하고 싶다면 ‘google’이라는 옵션을 주면 되고 이메일로만 로그인하고 싶다면 ‘email’이라는 옵션을 통해 다양하게 로그인을 지원한다.
옵션을 부여했다면 매개변수로 넘겨줄 값들을 객체로 넘겨주면 로그인의 대한 준비는 끝난다.
ID, Password를 통한 로그인뿐만 아니라 소셜 로그인을 통한 로그인도 전부 여기서 시작한다고 봐도 무관하다.
import NextAuth, { NextAuthOptions } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
const authOptions: NextAuthOptions = {
session: {
strategy: "jwt",
},
providers: [
CredentialsProvider({
type: "credentials",
credentials: {},
async authorize(credentials, req) {
const { username, password } = credentials as {
username: string;
password: string;
};
return { id: username, name: username };
},
}),
],
pages: {
signIn: "/auth/signin",
error: "/auth/error",
signOut: "/auth/signout",
},
callbacks: {
async jwt({ token, account }) {
if (account) {
token.accessToken = account.access_token;
}
return token;
},
async session({ session, token, user }) {
if (token) {
session.user.accessToken = token.accessToken as string;
}
return session;
},
},
};
export default NextAuth(authOptions);
실질적으로 NextAuth를 사용하기 위해서 가장 중요한 것은 […nextauth].ts(js) 부분인데 이게 이 라이브러리의 핵심이라고 생각해도 무관하다.
그리고 가장 중요한 부분이 authorize라는 부분인데 signin 함수를 통해 매개변수로 넘겼던 ID와 Password 정보를 활용하여 로그인의 기능을 구현할 수 있다. 마지막으로 NextAuth에서 지원하는 Callbacks로 JWT의 대한 환경이나 전역적으로 사용할 Session의 값들을 넘겨주며 사용하면 된다.
[...nextAuth].ts(js)에서의 Flow는 Providers에서 만든 로그인 정보를 jwt callback에서 먼저 호출 뒤 session callback으로 넘어간다. 먼저 jwt의 정보를 넣고 그다음 session의 대한 정보를 넣으면 전역적으로 useSesison Hook으로 Client에서 유저 정보의 값을 불러와 해당 로그인된 사용자의 정보를 얻을 수 있다.
마무리😊
NextAuth는 로그인 로직을 정말 간단하게 도와주는 유용한 라이브러리가 아닐까 싶다. 그리고 활용도가 굉장히 높은 것 같다.
위 예제에서는 정말 간단하게 구현하는 방법의 대해서 소개했지만 당연히 API 통신을 통해서 로그인된 사용자 정보를 가져올 수 있고, Refersh Token을 얻는 방법 또한 매우 간단하다고 생각된다.
항상 로그인 기능이라는 게 정말 구현하기 까다롭고 복잡하고 때로는 생각을 많이 해야 되는 작업 중에 하나다.
물론 자신이 구현해보는 것이 제일 좋은 방법이긴 하나 각종 다양한 라이브러리를 사용하는 것도 어쩌면 다양한 프로젝트를 경험하는 개발자 인생에서 도움이 되지 않을까 싶다.
'Front-End > Next.js & React.js' 카테고리의 다른 글
Next.js - SSR Cookie Setting (0) | 2023.02.12 |
---|---|
React.js - Button onClick으로 부모의 onChangeHandler 이벤트 발생 시키기 (0) | 2023.01.24 |
React.js - 부모에서 자식 함수 호출하기 (0) | 2022.10.17 |
Next.js - Component cannot be used as a JSX component (2) | 2022.04.12 |
Next.js - Rewrites (0) | 2022.02.13 |