가이드

인증이란? 로그인, 세션, OAuth를 쉽게 설명

인증은 앱이 사용자가 누구인지 확인하는 방법입니다. 보통 사용자가 알고 있는 것(비밀번호), 가지고 있는 것(휴대폰이나 이메일로 받은 코드), 또는 신뢰할 수 있는 다른 서비스가 증명하는 신원(예: "Google로 로그인")을 확인합니다. 사용자가 인증되면 앱은 세션이나 토큰으로 그 사용자를 기억하므로, 페이지를 옮길 때마다 다시 로그인하지 않아도 됩니다. 인증된 사용자가 무엇을 할 수 있는지 정하는 것은 별도의 단계이며, 이를 권한 부여(authorization)라고 합니다.

AI로 만들 때 인증이 중요한 이유

로그인 기능 추가는 사람들이 AI 빌더에게 가장 많이 요청하는 기능 중 하나이며, 미묘하게 잘못 만들기 쉬운 기능이기도 합니다. 로그인 페이지는 간단히 만들 수 있지만, 어려운 부분은 그 주변 전부입니다.

  • 비밀번호가 안전하게 저장되나요?
  • 모든 비공개 페이지와 모든 API 엔드포인트가 실제로 요청자를 확인하나요?
  • 로그인한 고객이 URL의 숫자만 바꿔서 다른 고객의 데이터를 볼 수 있나요?
  • 사용자가 비밀번호를 잊어버리면 어떻게 되나요?

겉으로는 안전해 보이는 앱도 위의 항목 하나하나에서 실패할 수 있습니다. 작동 원리를 이해하면 올바른 질문을 하고 올바른 것을 테스트할 수 있습니다.

일상의 비유

호텔에 체크인하는 상황을 생각해 보세요.

프런트 데스크에서 신분증을 보여 줍니다. 이것이 인증, 즉 누구인지 증명하는 과정입니다. 직원은 이어서 키카드를 줍니다. 이 카드가 세션입니다. 숙박하는 동안 신분증을 다시 보여 줄 필요 없이 카드를 대면 됩니다.

카드는 객실, 헬스장, 여러분의 층으로 가는 엘리베이터는 열지만, 다른 투숙객의 객실이나 직원 사무실은 열지 못합니다. 이것이 권한 부여, 즉 신원이 무엇에 접근할 수 있는지입니다. 카드를 잃어버리면 호텔은 데스크에서 카드를 비활성화할 수 있습니다(세션 취소). 체크아웃하면 카드는 더 이상 작동하지 않습니다(로그아웃 또는 만료).

"Google로 로그인"은 호텔이 여러분의 신분증을 직접 확인하는 대신, 신뢰하는 파트너가 "이 사람이 맞습니다"라고 써 준 편지를 받아들이는 것과 같습니다.

주요 로그인 방식

방식작동 방식장점단점
이메일 + 비밀번호사용자가 비밀번호를 정하고, 앱은 그 해시를 저장합니다.익숙하고 외부 의존성이 없습니다.해시를 안전하게 저장하고 재설정을 처리해야 합니다.
매직 링크 / 일회용 코드앱이 로그인 링크나 코드를 이메일로 보냅니다.유출되거나 잊을 비밀번호가 없습니다.이메일 전달에 의존하며, 로그인이 더 느립니다.
소셜 로그인(OAuth / OpenID Connect)사용자가 Google, Apple, GitHub 등으로 로그인합니다.사용자에게 빠르고, 비밀번호를 직접 저장하지 않습니다.제공업체마다 설정이 필요하며, 해당 계정이 없는 사용자는 이용할 수 없습니다.
호스팅된 인증 제공업체Clerk, Auth0, Supabase Auth 같은 서비스가 가입, 로그인, 재설정을 처리합니다.보안 작업을 덜 해도 됩니다.규모가 커지면 월 비용이 들고, 또 하나의 의존성이 생깁니다.
다중 인증(MFA / 2FA)첫 번째 확인 뒤에 인증 앱 코드 같은 두 번째 확인을 요구합니다.침입이 훨씬 어렵습니다.약간의 번거로움이 추가됩니다.

비밀번호는 어떻게 저장해야 하나요

안전한 앱은 실제 비밀번호를 저장하지 않습니다. 대신 해시를 저장합니다. 해시는 비밀번호를 고정된 길이의 문자열로 바꾸는 단방향 함수의 결과입니다. 로그인할 때 앱은 입력된 값을 해시하고, 그 결과를 저장된 해시와 비교합니다.

이를 안전하게 만드는 두 가지 세부 사항이 있습니다.

  • 솔트: 해시하기 전에 각 비밀번호에 더하는 임의의 값입니다. 같은 비밀번호를 쓰는 두 사람도 서로 다른 해시를 얻으므로, 미리 계산해 둔 조회 표가 소용없어집니다.
  • 비밀번호용으로 설계된 느린 알고리즘: Argon2, bcrypt, scrypt 같은 알고리즘입니다. MD5나 SHA-256 같은 범용 해시는 그 자체로 너무 빨라서, 공격자가 수십억 번의 추측을 시도할 수 있습니다.

해싱은 암호화와 같지 않습니다. 암호화된 데이터는 키로 복호화할 수 있지만, 비밀번호 해시는 애초에 되돌릴 수 없도록 설계되어 있습니다.

세션 vs 토큰

로그인 후 앱은 각 요청마다 사용자를 알아봐야 합니다. 이를 처리하는 대표적인 방법은 두 가지입니다.

구분세션(쿠키)토큰(예: JWT)
브라우저가 가지는 것쿠키에 담긴 임의의 세션 ID사용자 정보와 만료 시각이 담긴 서명된 토큰
로그인 상태가 저장되는 곳서버의 데이터베이스나 저장소토큰 자체 안
모든 기기에서 강제 로그아웃쉽습니다. 서버에서 세션을 삭제하면 됩니다.어렵습니다. 차단 목록을 따로 관리하지 않으면 만료될 때까지 토큰이 유효합니다.
일반적인 용도전통적인 웹 앱API, 모바일 앱, 서비스 간 통신

쿠키에는 세 가지 설정이 중요합니다. HttpOnly(페이지의 JavaScript가 쿠키를 읽을 수 없게 함), Secure(HTTPS로만 전송), SameSite(다른 사이트에서 보내는 요청에 대한 전송을 제한)입니다. 토큰을 브라우저의 localStorage에 저장하는 방식도 흔하지만, 페이지에서 실행되는 모든 스크립트에 토큰이 노출됩니다.

OAuth와 "Google로 로그인"

OAuth 2.0은 위임된 권한 부여를 위한 표준입니다. 앱이 여러분의 Google 비밀번호를 전혀 보지 않고도, 다른 서비스의 계정에 제한된 접근 권한을 얻을 수 있게 해 줍니다. 예를 들어 Google 캘린더를 읽는 경우입니다. 여러분은 Google로 이동해 특정 권한(스코프라고 부릅니다)을 승인하고, Google은 그 권한에만 해당하는 토큰을 앱에 발급합니다.

OAuth만으로는 원래 접근을 허용하기 위해 설계되었지, 사용자가 누구인지 말해 주기 위해 설계된 것이 아닙니다. **OpenID Connect(OIDC)**는 OAuth 2.0 위에 신원 기능을 더한 계층이며, "Google로 로그인"이나 "Apple로 로그인"이 이를 사용합니다. 설정하려면 제공업체에 앱을 등록하고 클라이언트 ID와 클라이언트 시크릿을 받아야 합니다. 클라이언트 시크릿은 서버에 보관해야 합니다.

실제 예시: 고객 포털 로그인

디자인 에이전시의 고객이 프로젝트와 청구서를 확인할 수 있는 포털을 만든다고 해 봅시다.

  • 인증: 고객은 이메일과 매직 링크로 로그인하므로 관리할 비밀번호가 없습니다. 에이전시 직원은 Google Workspace 계정으로 로그인합니다.
  • 역할: 각 사용자는 client 또는 staff 역할을 가집니다.
  • 권한 규칙:
작업고객직원
자기 회사의 프로젝트 보기예예
다른 회사의 프로젝트 보기아니요예
프로젝트에 파일 업로드자기 프로젝트만예
청구서를 결제 완료로 표시아니요예
  • 적용 위치: 모든 요청에 대해 서버에서 적용합니다. 서버는 로그인한 사용자를 찾은 다음, project.company_id가 사용자의 회사와 일치하는 프로젝트만 반환합니다. "결제 완료" 버튼을 숨기는 것으로는 충분하지 않습니다. 엔드포인트 자체가 요청을 거부해야 합니다.

주요 용어

용어뜻
인증(AuthN)누군가가 누구인지 확인하는 것입니다.
권한 부여(AuthZ)그 사람이 무엇을 할 수 있는지 정하는 것입니다.
세션요청 사이에서 앱이 로그인 상태를 기억하는 것입니다.
쿠키브라우저가 요청마다 사이트에 다시 보내는 작은 데이터 조각입니다.
JWTJSON Web Token의 약자로, 사용자 ID와 만료 시각 같은 정보를 담은 서명된 소형 토큰입니다.
역할 / 권한접근을 결정하는 admin, member 같은 레이블입니다.
MFA / 2FA인증 앱의 코드처럼 두 번째 증명을 요구하는 것입니다.
SSO싱글 사인온입니다. 하나의 로그인(주로 회사 계정)으로 여러 앱에 접근합니다.
401 vs 403"당신은 누구인가요?"(인증되지 않음)와 "그것은 할 수 없습니다"(권한 없음)의 차이입니다.

흔한 실수와 오해

  • 페이지에서만 권한을 확인하는 경우. 브라우저가 버튼을 숨겨도 API가 확인하지 않으면, 누구든 API를 직접 호출할 수 있습니다.
  • URL의 ID를 그대로 믿는 경우. /invoices/1042는 청구서 1042가 로그인한 사용자의 것인지 확인해야 합니다.
  • 암호화를 직접 만드는 경우. 잘 알려진 라이브러리나 제공업체를 사용하세요. AI가 해싱 방식을 임의로 만들게 두지 마세요.
  • 약한 비밀번호 재설정. 재설정 링크는 한 번만 사용할 수 있어야 하고, 빨리 만료되어야 하며, 이메일로 계정 존재 여부를 알려 주면 안 됩니다.
  • 내 앱의 로그인과 빌더의 로그인을 혼동하는 경우. 앱의 사용자는 여러분이 앱을 만드는 도구의 계정과 별개입니다.
  • 로그인에 속도 제한이 없는 경우. 제한이 없으면 공격자가 비밀번호를 끝없이 시도할 수 있습니다.

AI 빌더에게 요청할 내용

  • "[잘 알려진 라이브러리나 제공업체]를 사용해 가입과 로그인을 추가해 줘. 비밀번호 해싱은 직접 작성하지 마."
  • "비밀번호는 bcrypt나 Argon2로 해시해서 저장해 줘."
  • "세션 쿠키는 HttpOnly, Secure 속성을 사용해 줘."
  • "역할을 admin과 member로 추가해 줘. 모든 엔드포인트와 각 엔드포인트를 호출할 수 있는 역할을 나열해 줘."
  • "사용자가 자기 레코드만 읽고 수정할 수 있도록 서버에서 강제해 줘. 그리고 어떻게 확인했는지 보여 줘."
  • "비밀번호 재설정을 추가하고, 1시간 뒤에 만료되는 일회용 링크를 사용해 줘."
  • "로그인 시도 횟수를 제한해 줘."

그다음 직접 테스트해 보세요. 계정을 두 개 만들고, 한 계정으로 로그인한 상태에서 다른 계정의 데이터에 접근해 보는 것입니다. 로그인 기능 추가 방법 가이드와 AI로 만든 앱 보안 체크리스트에서 더 자세한 내용을 확인할 수 있습니다.

Mythex에서의 인증

Mythex는 앱 사용자를 위한 기본 인증 제품을 제공하지 않습니다. 대신 접근 방식을 직접 선택하고, 에이전트에게 추가를 요청하면 됩니다. 프로젝트의 데이터베이스에 저장하는 이메일과 비밀번호 방식이나, 호스팅된 제공업체의 SDK를 사용하는 방식 중에서 고를 수 있습니다. 제공업체 키는 채팅이 아니라 프로젝트 비밀 값에 저장합니다. 이는 Mythex 자체에 로그인하는 방식과는 별개입니다. 문서의 앱에 로그인 추가하기 레시피에 시작 프롬프트가 있으니 이를 참고해 수정할 수 있습니다. 서버 측 검사가 어디에 있는지는 API란 무엇인가에서 설명합니다.

자주 묻는 질문

인증과 권한 부여의 차이는 무엇인가요?

인증은 당신이 누구인지 확인하는 과정입니다. 예를 들어 비밀번호를 검증하는 것이 여기에 해당합니다. 권한 부여는 신원이 확인된 뒤 무엇을 할 수 있는지 정하는 과정입니다. 예를 들어 관리자 페이지를 볼 수 있는지, 다른 사람의 예약을 수정할 수 있는지를 결정합니다. 앱에는 두 가지가 모두 필요합니다.

OAuth란 무엇인가요?

OAuth 2.0은 앱이 비밀번호를 보지 않고도 다른 서비스의 내 계정에 제한된 접근 권한을 얻을 수 있게 해 주는 표준입니다. 'Google로 로그인'은 OAuth 2.0 위에 구축된 신원 계층인 OpenID Connect를 사용하므로, 앱은 Google을 통해 사용자가 누구인지 알게 됩니다.

앱이 비밀번호를 저장해야 하나요?

읽을 수 있는 형태로는 절대 저장하면 안 됩니다. 이메일과 비밀번호로 로그인하는 경우에는 비밀번호를 솔트(salt)를 더한 해시로 저장해야 하며, 이때 Argon2나 bcrypt처럼 비밀번호용으로 설계된 느린 알고리즘을 써야 합니다. 많은 앱은 호스팅된 인증 제공업체, 소셜 로그인, 이메일 매직 링크를 사용해 이 문제를 피합니다.

세션과 토큰 중 앱은 무엇을 써야 하나요?

둘 다 가능합니다. 세션은 로그인 상태를 서버에 저장하고 브라우저에는 쿠키로 임의의 ID를 줍니다. 이 방식은 쉽게 취소할 수 있습니다. JWT 같은 토큰은 서명된 정보를 자체적으로 담고 있어서 API나 모바일 클라이언트에 적합하지만, 만료되기 전에 취소하기는 더 어렵습니다. 일반적인 웹 앱에서는 쿠키 기반 세션이 무난한 기본값입니다.

Mythex · Pricing · AI로 무엇이든 만들기 · 웹사이트 및 앱 템플릿 · Mythex 비교 · AI 앱 개발 용어집 · 무료 AI 앱 개발 도구 · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)