이전 장에서는 인보이스 라우트를 구축하며 양식 유효성 검사를 추가하고 접근성을 향상시켰습니다. 이번 장에서는 대시보드에 인증을 추가할 것입니다.
이번 장에서는...
다음과 같은 내용을 다룰 예정입니다.
인증이 무엇인지?
NextAuth.js를 사용하여 앱에 인증 추가하는 방법
미들웨어를 사용하여 사용자를 리디렉션하고 라우트를 보호하는 방법
React의 useFormStatus와 useFormState를 사용하여 보류 중인 상태와 양식 오류를 처리하는 방법
인증이란 무엇인가요?
인증은 현재 많은 웹 애플리케이션에서 중요한 부분입니다. 이는 시스템이 사용자 자신이 누구인지 확인하는 방법입니다.
안전한 웹사이트는 종종 사용자의 신원을 확인하는 여러 방법을 사용합니다. 예를 들어, 사용자 이름과 비밀번호를 입력한 후에도 사이트는 사용자의 장치로 인증 코드를 보내거나 Google Authenticator와 같은 외부 앱을 사용할 수 있습니다. 이러한 2단계 인증(2FA)은 보안을 높이는 데 도움이 됩니다. 비밀번호를 알고 있다고 해도 고유한 토큰 없이는 계정에 액세스할 수 없습니다.
인증 vs. 권한 부여
웹 개발에서 인증과 권한 부여는 서로 다른 역할을 합니다.
인증(Authentication) 은 사용자가 자기 자신인지 확인하는 것입니다. 사용자 이름과 비밀번호와 같은 것으로 신원을 증명합니다.
권한 부여(Authorization) 는 다음 단계입니다. 사용자의 신원이 확인되면 권한 부여는 사용자가 애플리케이션의 어떤 부분을 사용할 수 있는지 결정합니다.
그래서 인증은 누구인지 확인하고, 권한 부여는 애플리케이션에서 무엇을 할 수 있는지 또는 액세스할 수 있는지 결정합니다.
퀴즈 시간입니다!
지금까지 배운 내용을 테스트해보세요.
다음 중 인증과 권한 부여의 차이를 가장 잘 설명하는 것은 무엇일까요?
A: 인증은 액세스할 수 있는 것을 결정합니다. 권한 부여는 신원을 확인합니다.
B: 인증과 권한 부여는 모두 사용자가 액세스할 수 있는 애플리케이션의 부분을 결정합니다.
C: 인증은 신원을 확인합니다. 권한 부여는 액세스할 수 있는 것을 결정합니다.
D: 차이가 없습니다. 두 용어는 같은 의미를 갖습니다.
정답 확인
C: 인증은 신원을 확인합니다. 권한 부여는 액세스할 수 있는 것을 결정합니다.
정답입니다! 비슷하게 들리지만, 인증은 신원을 확인하고 권한 부여는 애플리케이션에서 무엇을 할 수 있는지를 결정합니다.
페이지가 <LoginForm />을 가져오는 것을 알 수 있는데, 이는 이 장에서 나중에 업데이트할 것입니다.
NextAuth.js
우리는 애플리케이션에 인증을 추가하기 위해 NextAuth.js를 사용할 것입니다. NextAuth.js는 세션 관리, 로그인 및 로그아웃, 인증의 다른 측면들을 관리하는 복잡성을 많이 숨겨줍니다. 이러한 기능들을 수동으로 구현할 수도 있지만, 이 과정은 시간이 많이 걸리고 오류가 발생할 수 있습니다. NextAuth.js는 이 과정을 간소화하여 Next.js 애플리케이션에서의 인증에 대한 통일된 솔루션을 제공합니다.
NextAuth.js 설정하기
터미널에서 다음 명령어를 실행하여 NextAuth.js를 설치하세요:
Terminal
npminstallnext-auth@beta
여기서 beta 버전의 NextAuth.js를 설치하고 있는데, 이는 Next.js 14와 호환됩니다.
다음으로, 애플리케이션을 위한 비밀 키를 생성하세요. 이 키는 쿠키를 암호화하는 데 사용되며 사용자 세션의 보안을 보장합니다. 다음 명령어를 터미널에서 실행하여 키를 생성할 수 있습니다:
Terminal
opensslrand-base6432
그런 다음, .env 파일의 AUTH_SECRET 변수에 생성된 키를 추가하세요:
.env
AUTH_SECRET=your-secret-key
인증을 제대로 사용하려면, Vercel 프로젝트의 환경 변수도 업데이트해야 합니다. Vercel에서 환경 변수를 추가하는 방법은 이 가이드를 참고하세요.
페이지 옵션 추가하기
프로젝트의 루트에 auth.config.ts 파일을 생성하고 authConfig 객체를 내보내세요. 이 객체에는 NextAuth.js의 구성 옵션이 포함됩니다. 현재는 pages 옵션만 포함될 것입니다:
pages 옵션을 사용하여 사용자 지정 로그인, 로그아웃 및 오류 페이지의 경로를 지정할 수 있습니다. 이는 필수는 아니지만, signIn: '/login'을 pages 옵션에 추가함으로써 사용자는 NextAuth.js의 기본 페이지 대신에 우리의 사용자 지정 로그인 페이지로 리디렉션됩니다.
Next.js 미들웨어를 사용하여 라우트 보호하기
다음으로 라우트를 보호하는 로직을 추가하세요. 이렇게 하면 사용자가 로그인하지 않은 경우 대시보드 페이지에 액세스할 수 없습니다.
authorized 콜백은 Next.js 미들웨어를 통해 페이지에 액세스할 권한이 있는지 확인하는 데 사용됩니다. 이는 요청이 완료되기 전에 호출되며 auth 및 request 속성을 포함하는 객체를 받습니다. auth 속성에는 사용자 세션이 포함되고, request 속성에는 들어오는 요청이 포함됩니다.
providers 옵션은 다른 로그인 옵션을 나열하는 배열입니다. 지금은 NextAuth 구성을 충족시키기 위해 빈 배열입니다. 이에 대해 자세히 배우는 것은 자격 증명 제공자 추가 섹션에서 알아볼 것입니다.
다음으로, authConfig 객체를 미들웨어 파일로 가져오기 위해 middleware.ts라는 파일을 프로젝트의 루트에 생성하고 다음 코드를 붙여넣으세요:
여기서 authConfig 객체를 사용하여 NextAuth.js를 초기화하고 auth 속성을 내보냅니다. 또한 미들웨어의 matcher 옵션을 사용하여 특정 경로에서 실행되도록 지정합니다.
이 작업에 미들웨어를 활용하는 장점은 보호된 라우트가 미들웨어가 인증을 확인하기 전에 렌더링되지 않는다는 것입니다. 이는 애플리케이션의 보안과 성능을 향상시킵니다.
비밀번호 해싱
데이터베이스에 저장하기 전에 비밀번호를 해싱하는 것이 좋습니다. 해싱은 비밀번호를 길이가 고정된 문자열로 변환하여 무작위로 보이게 만듭니다. 이는 사용자 데이터가 노출되더라도 보안 계층을 제공합니다.
seed.js 파일에서는 사용자의 비밀번호를 데이터베이스에 저장하기 전에 bcrypt라는 패키지를 사용하여 해싱했습니다. 이어서 사용자가 입력한 비밀번호가 데이터베이스의 비밀번호와 일치하는지 확인하기 위해 나중에 다시 사용할 것입니다. 그러나 이를 위해 bcrypt 패키지를 위한 별도의 파일을 만들어야 합니다. 이는 bcrypt가 Next.js 미들웨어에 사용할 수 없는 Node.js API에 의존하기 때문입니다.
다음으로 NextAuth.js를 위한 providers 옵션을 추가해야 합니다. providers는 Google 또는 GitHub과 같은 다양한 로그인 옵션을 나열하는 배열입니다. 이 강의에서는 자격 증명 제공자(Credentials provider)만 사용할 것입니다.