[Front-end] 개발자 공부

[개발 공부 57일차] Authentication, Authorization

MOLLY_ 2024. 3. 15. 07:29
728x90

< 목차 >
1. Authentication 구현하는 법
   - Authentication
   -
Authorization
2. 금일 소감

 

 

1. Authentication 구현하는 법

Authentication

웹 애플리케이션에 기본 이메일-비밀번호 인증을 추가하는 프로세스다. 이 방법은 기본적인 수준의 보안을 제공하지만 일반적인 보안 위협에 대한 보호를 강화하려면 OAuth 또는 비밀번호 없는 로그인과 같은 고급 옵션을 고려하는 것이 좋다.

 

  1. 사용자가 로그인 양식을 통해 자격 증명을 제출한다.
  2. 이 양식은 서버 작업을 호출한다.
  3. 인증에 성공하면 프로세스가 완료되어 사용자가 인증에 성공했음을 나타낸다.
  4. 인증에 실패하면 오류 메시지가 표시된다.

 


사용자가 자격 증명을 입력할 수 있는 로그인 양식 코드

import { authenticate } from '@/app/lib/actions'
 
export default function Page() {
  return (
    <form action={authenticate}>
      <input type="email" name="email" placeholder="Email" required />
      <input type="password" name="password" placeholder="Password" required />
      <button type="submit">Login</button>
    </form>
  )
}

 

 

위의 양식에는 사용자의 이메일과 비밀번호를 캡처하기 위한 두 개의 입력 필드가 있다. 제출 시, 인증 서버 액션을 호출한 뒤 서버 액션에서 인증 제공업체의 API를 호출하여 인증을 처리할 수 있다.

'use server'
 
import { signIn } from '@/auth'
 
export async function authenticate(_currentState: unknown, formData: FormData) {
  try {
    await signIn('credentials', formData)
  } catch (error) {
    if (error) {
      switch (error.type) {
        case 'CredentialsSignin':
          return 'Invalid credentials.'
        default:
          return 'Something went wrong.'
      }
    }
    throw error
  }
}

 

 

자격 증명을 처리한 후에는 아래와 같은  2가지 결과가 발생할 수 있다.

 

  • 로그인 인증 성공: 보호된 경로에 액세스하고 사용자 정보를 가져오는 등의 추가 작업을 시작할 수 있다.
  • 로그인 인증 실패: 자격 증명이 올바르지 않거나 오류가 발생한 경우, 이 함수는 해당 오류 메시지를 반환하여 인증 실패를 나타낸다.

 

마지막으로 login-form.tsx 컴포넌트에서 React의 useFormState를 사용하여 서버 액션을 호출하고 양식 오류를 처리하고, useFormStatus를 사용하여 양식의 보류 중인 상태를 처리할 수 있다.

'use client'
 
import { authenticate } from '@/app/lib/actions'
import { useFormState, useFormStatus } from 'react-dom'
 
export default function Page() {
  const [errorMessage, dispatch] = useFormState(authenticate, undefined)
 
  return (
    <form action={dispatch}>
      <input type="email" name="email" placeholder="Email" required />
      <input type="password" name="password" placeholder="Password" required />
      <div>{errorMessage && <p>{errorMessage}</p>}</div>
      <LoginButton />
    </form>
  )
}
 
function LoginButton() {
  const { pending } = useFormStatus()
 
  return (
    <button aria-disabled={pending} type="submit">
      Login
    </button>
  )
}

 

 

Authorization

사용자가 인증되면 사용자가 특정 경로를 방문하고 서버 작업으로 데이터를 변경하고 경로 핸들러를 호출하는 등의 작업을 수행할 수 있도록 허용해야 한다.

 


미들웨어로 경로 보호

Next.js의 미들웨어는 웹사이트의 여러 부분에 액세스할 수 있는 사용자를 제어하는 데 도움된다. 사용자 대시보드와 같은 영역을 보호하면서 마케팅 페이지와 같은 다른 페이지를 공개하는 데 중요하다. 모든 경로에 미들웨어를 적용하고 공개 액세스에 대한 예외를 지정하는 것이 좋다.

 

 

Next.js에서 인증용 미들웨어를 구현하는 방법

  1. 미들웨어 설정: 프로젝트의 루트 디렉터리에 middleware.ts 또는 .js 파일을 만든다. 인증 토큰 확인과 같이 사용자 액세스를 승인하는 로직을 포함한다.
  2. 보호된 경로 정의: 모든 경로에 권한 부여가 필요한 것은 아니며 미들웨어의 매칭 옵션을 사용하여 인증 확인이 필요하지 않은 경로를 지정한다.
  3. 미들웨어 로직: 사용자가 인증되었는지 확인하는 로직을 작성한다. 사용자 역할 또는 권한을 확인하여 경로 권한을 부여한다.
  4. 무단 액세스 처리: 권한이 없는 사용자를 로그인 또는 오류 페이지로 적절히 리디렉션한다.

 

 

미들웨어 파일 예시

import type { NextRequest } from 'next/server'
 
export function middleware(request: NextRequest) {
  const currentUser = request.cookies.get('currentUser')?.value
 
  if (currentUser && !request.nextUrl.pathname.startsWith('/dashboard')) {
    return Response.redirect(new URL('/dashboard', request.url))
  }
 
  if (!currentUser && !request.nextUrl.pathname.startsWith('/login')) {
    return Response.redirect(new URL('/login', request.url))
  }
}
 
export const config = {
  matcher: ['/((?!api|_next/static|_next/image|.*\\.png$).*)'],
}

 

 

app/page.tsx

import { redirect } from 'next/navigation'
 
export default function Page() {
  // Logic to determine if a redirect is needed
  const accessDenied = true
  if (accessDenied) {
    redirect('/login')
  }
 
  // Define other routes and logic
}

 

 

인증에 성공한 후에는 역할에 따라 사용자 탐색을 관리하는 것이 중요하다.

예를 들어, 관리자 사용자는 관리자 대시보드로 리디렉션되는 반면 일반 사용자는 다른 페이지로 이동할 수 있다. 이는 필요한 경우, 사용자에게 프로필을 작성하라는 메시지를 표시하는 등 역할별 환경과 조건부 탐색에 중요하다.

권한 부여를 설정할 때는 앱이 데이터에 액세스하거나 데이터를 변경하는 곳에서 주요 보안 검사가 이루어지도록 하는 것이 중요하다. 미들웨어는 초기 유효성 검사에 유용할 수 있지만, 데이터를 보호하는 유일한 방어선이 되어서는 안 된다. 대부분의 보안 검사는 데이터 액세스 계층(DAL)에서 수행되어야 한다.

 

 

만약, 포괄적인 보안을 보장하고 싶다면 다음과 같은 주요 영역을 고려하자

  • 서버 작업: 특히 민감한 작업에 대해 서버 측 프로세스에서 보안 검사를 구현합니다.
  • 라우트 핸들러보안 조치를 통해 들어오는 요청을 관리하여 권한이 있는 사용자로 액세스가 제한되도록 한다.
  • 데이터 액세스 계층(DAL): 데이터베이스와 직접 상호 작용하며 데이터 트랜잭션의 유효성을 검사하고 권한을 부여하는 데 중요하다. 가장 중요한 상호 작용 지점인 데이터 액세스 또는 수정 지점에서 데이터를 보호하려면 DAL 내에서 중요한 검사를 수행하는 것이 중요하다.

 

[Reference]

https://nextjs.org/docs/app/building-your-application/authentication#authentication

 

 

 

2. 금일 소감

휴... 주말에 열심히 공부해야겠다.. 매번 과제로 올라오는 것 말고 내가 하고 싶은 기능을 해보고 싶은 생각이 더 드는데, 그럴 때마다 '일단 올라온 필수부터 해야지' 하며 하느라 좀 미루기도 하고 필수 하고 제출하면 또 다른 거 해야 하고의 반복이다. 지금도 그러는 중... 휴 오늘 뭐 최대한 해서 제출하고 그냥 좀 쉬면서 내가 하고 싶은 기능이나 공부 해야겠다.

 

이해가 안 돼서 심화 공부를 절반 정도 안 했었는데 그게 타격이 좀 큰 것 같아서 어제는 심화 강의를 다시 들었다. 회피 심리인지 모르겠는데 공부하다가 잠도 오고, 어제는 감기 기운 때문에 편두통이랑 코감기가 심해서 좀 쉬었다. 오늘은 어쨌든 과제 마무리해서 제출해야겠다.

 

728x90