인증
- 소개
- 인증 퀵스타트
- 수동으로 사용자 인증하기
- HTTP 기본 인증
- 로그아웃
- 비밀번호 확인
- 사용자 정의 가드 추가
- 사용자 정의 사용자 프로바이더 추가
- 자동 비밀번호 재해시
- 소셜 인증
- 이벤트
소개
많은 웹 애플리케이션은 사용자가 애플리케이션으로 인증하고 "로그인"할 수 있는 방법을 제공합니다. 웹 애플리케이션에서 이 기능을 구현하는 것은 복잡하고 잠재적으로 위험한 작업이 될 수 있습니다. 이러한 이유로 Laravel은 인증을 빠르고 안전하고 쉽게 구현하는 데 필요한 도구를 제공하려고 노력합니다.
핵심적으로 Laravel의 인증 기능은 "가드"와 "프로바이더"로 구성됩니다. 가드는 각 요청에 대해 사용자를 인증하는 방법을 정의합니다. 예를 들어 Laravel은 세션 스토리지 및 쿠키를 사용하여 상태를 유지하는 session 가드와 함께 제공됩니다.
프로바이더는 영구 스토리지에서 사용자를 검색하는 방법을 정의합니다. Laravel은 Eloquent와 데이터베이스 쿼리 빌더를 사용하여 사용자를 검색하는 기능을 제공합니다. 그러나 애플리케이션에 필요한 경우 추가 프로바이더를 자유롭게 정의할 수 있습니다.
애플리케이션의 인증 구성 파일은 config/auth.php에 있습니다. 이 파일에는 Laravel의 인증 서비스의 동작을 조정하기 위한 여러 가지 잘 문서화된 옵션이 포함되어 있습니다.
가드와 프로바이더를 "역할"과 "권한"으로 혼동해서는 안 됩니다. 권한을 통해 사용자 작업에 권한을 부여하는 방법에 대한 자세한 내용은 인증 설명서를 참조하세요.
스타터 키트
빠르게 시작하고 싶으신가요? 새로운 Laravel 애플리케이션에 Laravel 애플리케이션 스타터 키트를 설치하세요. 데이터베이스를 마이그레이션한 후 브라우저에서 /register 또는 애플리케이션에 할당된 다른 URL로 이동하세요. 스타터 키트가 전체 인증 시스템의 스캐폴딩을 처리해 줍니다!
최종 Laravel 애플리케이션에서 스타터 키트를 사용하지 않기로 선택하더라도 Laravel Breeze 스타터 키트를 설치하는 것은 실제 Laravel 프로젝트에서 Laravel의 모든 인증 기능을 구현하는 방법을 배우는 훌륭한 기회가 될 수 있습니다. Laravel Breeze는 인증 컨트롤러, 라우트 및 보기를 생성하므로 이러한 파일 내의 코드를 검토하여 Laravel의 인증 기능이 구현될 수 있는 방법을 배울 수 있습니다.
데이터베이스 고려 사항
기본적으로 Laravel은 app/Models 디렉토리에 App\Models\User Eloquent 모델을 포함합니다. 이 모델은 기본 Eloquent 인증 드라이버와 함께 사용할 수 있습니다.
애플리케이션에서 Eloquent를 사용하지 않는 경우 Laravel 쿼리 빌더를 사용하는 database 인증 프로바이더를 사용할 수 있습니다. 애플리케이션에서 MongoDB를 사용하는 경우 MongoDB의 공식 Laravel 사용자 인증 설명서를 확인하세요.
App\Models\User 모델의 데이터베이스 스키마를 구축할 때 비밀번호 열이 최소 60자 이상인지 확인하세요. 물론 새 Laravel 애플리케이션에 포함된 users 테이블 마이그레이션은 이미 이 길이보다 긴 열을 만듭니다.
또한 users (또는 그에 상응하는) 테이블에 100자의 널 가능 문자열 remember_token 열이 포함되어 있는지 확인해야 합니다. 이 열은 애플리케이션에 로그인할 때 "나를 기억하기" 옵션을 선택하는 사용자의 토큰을 저장하는 데 사용됩니다. 다시 말하지만, 새로운 Laravel 애플리케이션에 포함된 기본 users 테이블 마이그레이션에는 이미 이 열이 포함되어 있습니다.
생태계 개요
Laravel은 인증과 관련된 여러 패키지를 제공합니다. 계속하기 전에 Laravel의 일반적인 인증 생태계를 검토하고 각 패키지의 용도에 대해 논의하겠습니다.
먼저 인증이 어떻게 작동하는지 생각해 보세요. 웹 브라우저를 사용하는 경우 사용자는 로그인 양식을 통해 사용자 이름과 비밀번호를 제공합니다. 이러한 자격 증명이 올바르면 애플리케이션은 인증된 사용자에 대한 정보를 사용자의 세션에 저장합니다. 브라우저에 발급된 쿠키에는 세션 ID가 포함되어 있어 이후의 애플리케이션 요청에서 사용자를 올바른 세션과 연결할 수 있습니다. 세션 쿠키를 수신한 후 애플리케이션은 세션 ID를 기반으로 세션 데이터를 검색하고, 인증 정보가 세션에 저장되었음을 확인하고, 사용자를 "인증됨"으로 간주합니다.
원격 서비스가 API에 액세스하기 위해 인증해야 하는 경우 웹 브라우저가 없기 때문에 쿠키는 일반적으로 인증에 사용되지 않습니다. 대신 원격 서비스는 각 요청 시 API 토큰을 API로 보냅니다. 애플리케이션은 들어오는 토큰을 유효한 API 토큰 테이블과 비교하여 유효성을 검사하고 해당 API 토큰과 연결된 사용자가 수행한 것으로 요청을 "인증"할 수 있습니다.
Laravel의 기본 제공 브라우저 인증 서비스
Laravel에는 일반적으로 Auth 및 Session 파사드를 통해 액세스하는 기본 제공 인증 및 세션 서비스가 포함되어 있습니다. 이러한 기능은 웹 브라우저에서 시작된 요청에 대한 쿠키 기반 인증을 제공합니다. 이를 통해 사용자의 자격 증명을 확인하고 사용자를 인증할 수 있는 메서드를 제공합니다. 또한 이러한 서비스는 사용자의 세션에 올바른 인증 데이터를 자동으로 저장하고 사용자 세션 쿠키를 발급합니다. 이러한 서비스 사용 방법에 대한 설명은 이 설명서에 포함되어 있습니다.
애플리케이션 스타터 키트
이 설명서에서 논의한 것처럼 이러한 인증 서비스를 수동으로 사용하여 애플리케이션 자체의 인증 레이어를 구축할 수 있습니다. 그러나 더 빠르게 시작하는 데 도움이 되도록 전체 인증 레이어의 강력하고 현대적인 스캐폴딩을 제공하는 무료 패키지를 출시했습니다. 이러한 패키지는 Laravel Breeze, Laravel Jetstream 및 Laravel Fortify입니다.
_Laravel Breeze_는 로그인, 등록, 비밀번호 재설정, 이메일 확인 및 비밀번호 확인을 포함하여 Laravel의 모든 인증 기능의 간단하고 최소한의 구현입니다. Laravel Breeze의 뷰 레이어는 Tailwind CSS로 스타일이 지정된 간단한 Blade 템플릿으로 구성됩니다. 시작하려면 Laravel의 애플리케이션 스타터 키트에 대한 설명서를 확인하세요.
_Laravel Fortify_는 쿠키 기반 인증은 물론 2단계 인증 및 이메일 확인과 같은 기타 기능을 포함하여 이 설명서에서 찾을 수 있는 많은 기능을 구현하는 Laravel용 헤드리스 인증 백엔드입니다. Fortify는 Laravel Jetstream의 인증 백엔드를 제공하거나 Laravel Sanctum과 함께 독립적으로 사용하여 Laravel로 인증해야 하는 SPA에 대한 인증을 제공할 수 있습니다.
_Laravel Jetstream_은 Tailwind CSS, Livewire 및/또는 Inertia를 기반으로 한 아름답고 현대적인 UI를 통해 Laravel Fortify의 인증 서비스를 소비하고 노출하는 강력한 애플리케이션 스타터 키트입니다. Laravel Jetstream에는 2단계 인증, 팀 지원, 브라우저 세션 관리, 프로필 관리, Laravel Sanctum과의 기본 제공 통합을 통해 API 토큰 인증을 제공하는 옵션 지원이 포함되어 있습니다. Laravel의 API 인증 제품은 아래에서 논의합니다.
Laravel의 API 인증 서비스
Laravel은 API 토큰을 관리하고 API 토큰으로 이루어진 요청을 인증하는 데 도움이 되는 두 가지 선택적 패키지인 Passport 및 Sanctum을 제공합니다. 이러한 라이브러리와 Laravel의 기본 제공 쿠키 기반 인증 라이브러리는 상호 배타적이지 않습니다. 이러한 라이브러리는 주로 API 토큰 인증에 중점을 두는 반면 기본 제공 인증 서비스는 쿠키 기반 브라우저 인증에 중점을 둡니다. 많은 애플리케이션에서 Laravel의 기본 제공 쿠키 기반 인증 서비스와 Laravel의 API 인증 패키지 중 하나를 모두 사용합니다.
Passport
Passport는 다양한 유형의 토큰을 발급할 수 있는 다양한 OAuth2 "승인 유형"을 제공하는 OAuth2 인증 프로바이더입니다. 일반적으로 이는 API 인증을 위한 강력하고 복잡한 패키지입니다. 그러나 대부분의 애플리케이션에서는 OAuth2 사양에서 제공하는 복잡한 기능이 필요하지 않으며, 이는 사용자와 개발자 모두에게 혼란스러울 수 있습니다. 또한 개발자는 과거에 Passport와 같은 OAuth2 인증 프로바이더를 사용하여 SPA 애플리케이션 또는 모바일 애플리케이션을 인증하는 방법에 대해 혼란스러워했습니다.
Sanctum
OAuth2의 복잡성과 개발자의 혼란에 대응하여 웹 브라우저의 1차 웹 요청과 토큰을 통한 API 요청을 모두 처리할 수 있는 더 간단하고 간소화된 인증 패키지를 구축하기 시작했습니다. 이 목표는 백엔드 Laravel 애플리케이션과 별도로 존재하는 단일 페이지 애플리케이션(SPA) 또는 모바일 클라이언트를 제공하는 애플리케이션 외에도 1차 웹 UI를 제공할 애플리케이션에 권장되는 인증 패키지로 간주되어야 하는 Laravel Sanctum을 출시하여 실현되었습니다.
Laravel Sanctum은 애플리케이션의 전체 인증 프로세스를 관리할 수 있는 하이브리드 웹/API 인증 패키지입니다. Sanctum 기반 애플리케이션이 요청을 수신하면 Sanctum은 먼저 요청에 인증된 세션을 참조하는 세션 쿠키가 포함되어 있는지 여부를 확인하기 때문에 이것이 가능합니다. Sanctum은 앞서 논의한 Laravel의 기본 제공 인증 서비스를 호출하여 이를 수행합니다. 세션 쿠키를 통해 요청이 인증되지 않으면 Sanctum은 API 토큰에 대한 요청을 검사합니다. API 토큰이 있으면 Sanctum은 해당 토큰을 사용하여 요청을 인증합니다. 이 프로세스에 대해 자세히 알아보려면 Sanctum의 "작동 방식" 설명서를 참조하세요.
Laravel Sanctum은 대부분의 웹 애플리케이션의 인증 요구 사항에 가장 적합하다고 생각하기 때문에 Laravel Jetstream 애플리케이션 스타터 키트에 포함하기로 선택한 API 패키지입니다.
요약 및 스택 선택
요약하자면, 애플리케이션이 브라우저를 사용하여 액세스되고 모놀리식 Laravel 애플리케이션을 구축하는 경우 애플리케이션은 Laravel의 기본 제공 인증 서비스를 사용합니다.
다음으로, 애플리케이션에서 타사에서 사용할 API를 제공하는 경우 애플리케이션에 대한 API 토큰 인증을 제공하기 위해 Passport 또는 Sanctum 중에서 선택합니다. 일반적으로 Sanctum은 "범위" 또는 "기능"에 대한 지원을 포함하여 API 인증, SPA 인증 및 모바일 인증을 위한 간단하고 완전한 솔루션이기 때문에 가능하면 선호해야 합니다.
Laravel 백엔드를 기반으로 하는 단일 페이지 애플리케이션(SPA)을 구축하는 경우 Laravel Sanctum을 사용해야 합니다. Sanctum을 사용하는 경우 수동으로 자체 백엔드 인증 라우트를 구현하거나 Laravel Fortify를 등록, 비밀번호 재설정, 이메일 확인 등과 같은 기능에 대한 라우트 및 컨트롤러를 제공하는 헤드리스 인증 백엔드 서비스로 활용해야 합니다.
Passport는 애플리케이션에 OAuth2 사양에서 제공하는 모든 기능이 절대적으로 필요한 경우에 선택할 수 있습니다.
그리고 빠르게 시작하고 싶다면 Laravel의 기본 제공 인증 서비스와 Laravel Sanctum의 선호하는 인증 스택을 이미 사용하는 새로운 Laravel 애플리케이션을 시작하는 빠른 방법으로 Laravel Breeze를 추천하게 되어 기쁩니다.
인증 퀵스타트
이 문서 부분에서는 빠르게 시작하는 데 도움이 되는 UI 스캐폴딩이 포함된 Laravel 애플리케이션 스타터 키트를 통해 사용자 인증에 대해 설명합니다. Laravel의 인증 시스템과 직접 통합하려면 수동으로 사용자 인증하기에 대한 설명서를 확인하세요.
스타터 키트 설치
먼저 Laravel 애플리케이션 스타터 키트를 설치해야 합니다. 현재 스타터 키트인 Laravel Breeze와 Laravel Jetstream은 새로운 Laravel 애플리케이션에 인증을 통합하기 위한 멋지게 디자인된 시작점을 제공합니다.
Laravel Breeze는 로그인, 등록, 비밀번호 재설정, 이메일 확인 및 비밀번호 확인을 포함하여 Laravel의 모든 인증 기능의 최소한의 간단한 구현입니다. Laravel Breeze의 뷰 레이어는 Tailwind CSS로 스타일이 지정된 간단한 Blade 템플릿으로 구성됩니다. 또한 Breeze는 Livewire 또는 Inertia를 기반으로 하는 스캐폴딩 옵션을 제공하며, Inertia 기반 스캐폴딩에는 Vue 또는 React를 선택할 수 있습니다.
Laravel Jetstream은 Livewire 또는 Inertia 및 Vue로 애플리케이션을 스캐폴딩하기 위한 지원을 포함하는 보다 강력한 애플리케이션 스타터 키트입니다. 또한 Jetstream은 2단계 인증, 팀, 프로필 관리, 브라우저 세션 관리, Laravel Sanctum을 통한 API 지원, 계정 삭제 등에 대한 옵션 지원을 제공합니다.
인증된 사용자 검색
인증 스타터 키트를 설치하고 사용자가 애플리케이션에 등록하고 인증하도록 허용한 후에는 종종 현재 인증된 사용자와 상호 작용해야 합니다. 들어오는 요청을 처리하는 동안 Auth 파사드의 user 메서드를 통해 인증된 사용자에게 액세스할 수 있습니다.
use Illuminate\Support\Facades\Auth; // 현재 인증된 사용자 검색...$user = Auth::user(); // 현재 인증된 사용자의 ID 검색...$id = Auth::id();
또는 사용자가 인증된 후에는 Illuminate\Http\Request 인스턴스를 통해 인증된 사용자에게 액세스할 수 있습니다. 유형 힌트된 클래스는 컨트롤러 메서드에 자동으로 삽입됩니다. Illuminate\Http\Request 객체에 유형 힌트를 지정하면 애플리케이션의 모든 컨트롤러 메서드에서 요청의 user 메서드를 통해 인증된 사용자에게 편리하게 액세스할 수 있습니다.
<?php namespace App\Http\Controllers; use Illuminate\Http\RedirectResponse;use Illuminate\Http\Request; class FlightController extends Controller{ /** * 기존 비행의 비행 정보를 업데이트합니다. */ public function update(Request $request): RedirectResponse { $user = $request->user(); // ... return redirect('/flights'); }}
현재 사용자가 인증되었는지 확인
들어오는 HTTP 요청을 하는 사용자가 인증되었는지 확인하려면 Auth 파사드에서 check 메서드를 사용할 수 있습니다. 이 메서드는 사용자가 인증된 경우 true를 반환합니다.
use Illuminate\Support\Facades\Auth; if (Auth::check()) { // 사용자가 로그인했습니다...}
check 메서드를 사용하여 사용자가 인증되었는지 확인할 수 있지만, 일반적으로 사용자가 특정 라우트/컨트롤러에 액세스할 수 있도록 허용하기 전에 미들웨어를 사용하여 사용자가 인증되었는지 확인합니다. 이에 대해 자세히 알아보려면 라우트 보호에 대한 설명서를 확인하세요.
라우트 보호
라우트 미들웨어는 인증된 사용자만 특정 라우트에 액세스하도록 허용하는 데 사용할 수 있습니다. Laravel은 Illuminate\Auth\Middleware\Authenticate 클래스에 대한 미들웨어 별칭인 auth 미들웨어를 제공합니다. 이 미들웨어가 Laravel에서 내부적으로 이미 별칭이 지정되어 있으므로 라우트 정의에 미들웨어를 연결하기만 하면 됩니다.
Route::get('/flights', function () { // 인증된 사용자만 이 라우트에 액세스할 수 있습니다...})->middleware('auth');
인증되지 않은 사용자 리디렉션
auth 미들웨어가 인증되지 않은 사용자를 감지하면 사용자를 login 명명된 라우트로 리디렉션합니다. 애플리케이션의 bootstrap/app.php 파일의 redirectGuestsTo 메서드를 사용하여 이 동작을 수정할 수 있습니다.
use Illuminate\Http\Request; ->withMiddleware(function (Middleware $middleware) { $middleware->redirectGuestsTo('/login'); // 클로저 사용... $middleware->redirectGuestsTo(fn (Request $request) => route('login'));})
가드 지정
라우트에 auth 미들웨어를 연결할 때 사용자를 인증하는 데 사용해야 하는 "가드"를 지정할 수도 있습니다. 지정된 가드는 auth.php 구성 파일의 guards 배열에 있는 키 중 하나에 해당해야 합니다.
Route::get('/flights', function () { // 인증된 사용자만 이 라우트에 액세스할 수 있습니다...})->middleware('auth:admin');
로그인 스로틀링
Laravel Breeze 또는 Laravel Jetstream 스타터 키트를 사용하는 경우 로그인 시도에 속도 제한이 자동으로 적용됩니다. 기본적으로 사용자는 여러 번 시도한 후 올바른 자격 증명을 제공하지 못하면 1분 동안 로그인할 수 없습니다. 스로틀링은 사용자의 사용자 이름/이메일 주소와 해당 IP 주소에 고유합니다.
애플리케이션의 다른 라우트에 속도 제한을 적용하려면 속도 제한 문서를 확인하세요.
수동으로 사용자 인증하기
Laravel의 애플리케이션 스타터 키트에 포함된 인증 스캐폴딩을 사용할 필요는 없습니다. 이 스캐폴딩을 사용하지 않기로 선택한 경우 Laravel 인증 클래스를 직접 사용하여 사용자 인증을 관리해야 합니다. 걱정하지 마세요. 간단합니다!
Auth 파사드를 통해 Laravel의 인증 서비스에 액세스할 것이므로 클래스 맨 위에 Auth 파사드를 가져와야 합니다. 다음으로 attempt 메서드를 확인해 보겠습니다. attempt 메서드는 일반적으로 애플리케이션의 "로그인" 양식에서 인증 시도를 처리하는 데 사용됩니다. 인증에 성공하면 세션 고정을 방지하기 위해 사용자의 세션을 재생성해야 합니다.
<?php namespace App\Http\Controllers; use Illuminate\Http\Request;use Illuminate\Http\RedirectResponse;use Illuminate\Support\Facades\Auth; class LoginController extends Controller{ /** * 인증 시도를 처리합니다. */ public function authenticate(Request $request): RedirectResponse { $credentials = $request->validate([ 'email' => ['required', 'email'], 'password' => ['required'], ]); if (Auth::attempt($credentials)) { $request->session()->regenerate(); return redirect()->intended('dashboard'); } return back()->withErrors([ 'email' => '제공된 자격 증명이 기록과 일치하지 않습니다.', ])->onlyInput('email'); }}
attempt 메서드는 키/값 쌍의 배열을 첫 번째 인수로 허용합니다. 배열의 값은 데이터베이스 테이블에서 사용자를 찾는 데 사용됩니다. 따라서 위의 예에서 사용자는 email 열의 값으로 검색됩니다. 사용자가 발견되면 데이터베이스에 저장된 해시된 비밀번호가 배열을 통해 메서드에 전달된 password 값과 비교됩니다. 프레임워크가 데이터베이스의 해시된 비밀번호와 비교하기 전에 값을 자동으로 해시하므로 들어오는 요청의 password 값을 해시해서는 안 됩니다. 두 개의 해시된 비밀번호가 일치하면 사용자에 대한 인증된 세션이 시작됩니다.
Laravel의 인증 서비스는 인증 가드의 "프로바이더" 구성에 따라 데이터베이스에서 사용자를 검색합니다. 기본 config/auth.php 구성 파일에서 Eloquent 사용자 프로바이더가 지정되고 사용자를 검색할 때 App\Models\User 모델을 사용하도록 지시됩니다. 애플리케이션의 필요에 따라 구성 파일 내에서 이러한 값을 변경할 수 있습니다.
attempt 메서드는 인증에 성공하면 true를 반환합니다. 그렇지 않으면 false가 반환됩니다.
Laravel의 리디렉터에서 제공하는 intended 메서드는 사용자가 인증 미들웨어에 의해 가로채기 전에 액세스하려고 했던 URL로 사용자를 리디렉션합니다. 의도한 대상이 없는 경우 이 메서드에 대체 URI를 제공할 수 있습니다.
추가 조건 지정
원하는 경우 사용자의 이메일과 비밀번호 외에 인증 쿼리에 추가 쿼리 조건을 추가할 수도 있습니다. 이를 위해 attempt 메서드에 전달된 배열에 쿼리 조건을 추가하기만 하면 됩니다. 예를 들어 사용자가 "활성"으로 표시되어 있는지 확인할 수 있습니다.
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) { // 인증에 성공했습니다...}
복잡한 쿼리 조건의 경우 자격 증명 배열에 클로저를 제공할 수 있습니다. 이 클로저는 쿼리 인스턴스와 함께 호출되어 애플리케이션의 필요에 따라 쿼리를 사용자 지정할 수 있습니다.
use Illuminate\Database\Eloquent\Builder; if (Auth::attempt([ 'email' => $email, 'password' => $password, fn (Builder $query) => $query->has('activeSubscription'),])) { // 인증에 성공했습니다...}
이러한 예에서 email은 필수 옵션이 아니라 예로 사용될 뿐입니다. 데이터베이스 테이블의 "사용자 이름"에 해당하는 열 이름을 사용해야 합니다.
두 번째 인수로 클로저를 받는 attemptWhen 메서드를 사용하여 사용자를 실제로 인증하기 전에 잠재적 사용자를 더 광범위하게 검사할 수 있습니다. 클로저는 잠재적 사용자를 받고 사용자를 인증할 수 있는지 여부를 나타내기 위해 true 또는 false를 반환해야 합니다.
if (Auth::attemptWhen([ 'email' => $email, 'password' => $password,], function (User $user) { return $user->isNotBanned();})) { // 인증에 성공했습니다...}
특정 가드 인스턴스 액세스
Auth 파사드의 guard 메서드를 통해 사용자를 인증할 때 사용하고 싶은 가드 인스턴스를 지정할 수 있습니다. 이를 통해 완전히 별도의 인증 가능한 모델 또는 사용자 테이블을 사용하여 애플리케이션의 별도 부분에 대한 인증을 관리할 수 있습니다.
guard 메서드에 전달된 가드 이름은 auth.php 구성 파일에 구성된 가드 중 하나에 해당해야 합니다.
if (Auth::guard('admin')->attempt($credentials)) { // ...}
사용자 기억하기
많은 웹 애플리케이션에서 로그인 양식에 "나를 기억하기" 확인란을 제공합니다. 애플리케이션에서 "나를 기억하기" 기능을 제공하려면 attempt 메서드에 부울 값을 두 번째 인수로 전달할 수 있습니다.
이 값이 true이면 Laravel은 사용자가 수동으로 로그아웃할 때까지 또는 무기한으로 인증 상태를 유지합니다. users 테이블에는 "나를 기억하기" 토큰을 저장하는 데 사용될 문자열 remember_token 열이 포함되어야 합니다. 새로운 Laravel 애플리케이션에 포함된 users 테이블 마이그레이션에는 이미 이 열이 포함되어 있습니다.
use Illuminate\Support\Facades\Auth; if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) { // 사용자를 기억하고 있습니다...}
애플리케이션에서 "나를 기억하기" 기능을 제공하는 경우 viaRemember 메서드를 사용하여 현재 인증된 사용자가 "나를 기억하기" 쿠키를 사용하여 인증되었는지 여부를 확인할 수 있습니다.
use Illuminate\Support\Facades\Auth; if (Auth::viaRemember()) { // ...}
다른 인증 방법
사용자 인스턴스 인증
기존 사용자 인스턴스를 현재 인증된 사용자로 설정해야 하는 경우 Auth 파사드의 login 메서드에 사용자 인스턴스를 전달할 수 있습니다. 지정된 사용자 인스턴스는 Illuminate\Contracts\Auth\Authenticatable 계약의 구현이어야 합니다. Laravel에 포함된 App\Models\User 모델은 이미 이 인터페이스를 구현합니다. 이 인증 방법은 사용자가 애플리케이션에 등록한 직후와 같이 이미 유효한 사용자 인스턴스가 있는 경우에 유용합니다.
use Illuminate\Support\Facades\Auth; Auth::login($user);
login 메서드에 부울 값을 두 번째 인수로 전달할 수 있습니다. 이 값은 인증된 세션에 대해 "나를 기억하기" 기능이 필요한지 여부를 나타냅니다. 이것은 세션이 무기한으로 인증되거나 사용자가 애플리케이션에서 수동으로 로그아웃할 때까지 인증됨을 의미합니다.
Auth::login($user, $remember = true);
필요한 경우 login 메서드를 호출하기 전에 인증 가드를 지정할 수 있습니다.
Auth::guard('admin')->login($user);
ID로 사용자 인증
데이터베이스 레코드의 기본 키를 사용하여 사용자를 인증하려면 loginUsingId 메서드를 사용할 수 있습니다. 이 메서드는 인증하려는 사용자의 기본 키를 허용합니다.
Auth::loginUsingId(1);
loginUsingId 메서드의 remember 인수에 부울 값을 전달할 수 있습니다. 이 값은 인증된 세션에 대해 "나를 기억하기" 기능이 필요한지 여부를 나타냅니다. 이것은 세션이 무기한으로 인증되거나 사용자가 애플리케이션에서 수동으로 로그아웃할 때까지 인증됨을 의미합니다.
Auth::loginUsingId(1, remember: true);
한 번 사용자 인증
once 메서드를 사용하여 단일 요청에 대해 애플리케이션으로 사용자를 인증할 수 있습니다. 이 메서드를 호출할 때 세션이나 쿠키는 사용되지 않습니다.
if (Auth::once($credentials)) { // ...}
HTTP 기본 인증
HTTP 기본 인증은 전용 "로그인" 페이지를 설정하지 않고도 애플리케이션 사용자를 인증하는 빠른 방법을 제공합니다. 시작하려면 라우트에 auth.basic 미들웨어를 연결합니다. auth.basic 미들웨어는 Laravel 프레임워크에 포함되어 있으므로 정의할 필요가 없습니다.
Route::get('/profile', function () { // 인증된 사용자만 이 라우트에 액세스할 수 있습니다...})->middleware('auth.basic');
미들웨어가 라우트에 연결되면 브라우저에서 라우트에 액세스할 때 자격 증명을 묻는 메시지가 자동으로 표시됩니다. 기본적으로 auth.basic 미들웨어는 users 데이터베이스 테이블의 email 열이 사용자의 "사용자 이름"이라고 가정합니다.
FastCGI에 대한 참고 사항
PHP FastCGI와 Apache를 사용하여 Laravel 애플리케이션을 제공하는 경우 HTTP 기본 인증이 제대로 작동하지 않을 수 있습니다. 이러한 문제를 해결하려면 애플리케이션의 .htaccess 파일에 다음 줄을 추가할 수 있습니다.
# HTTP Authorization 헤더가 존재하는지 확인합니다.RewriteCond %{HTTP:Authorization} ^(.+)$# 모든 요청에 대해 HTTP_AUTHORIZATION 환경 변수에 Authorization 헤더 값을 저장합니다.RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
상태 비저장 HTTP 기본 인증
세션에 사용자 식별자 쿠키를 설정하지 않고도 HTTP 기본 인증을 사용할 수 있습니다. 이는 주로 HTTP 인증을 사용하여 애플리케이션 API에 대한 요청을 인증하려는 경우에 유용합니다. 이를 수행하려면 onceBasic 메서드를 호출하는 미들웨어를 정의하세요. onceBasic 메서드에서 응답이 반환되지 않으면 요청이 애플리케이션으로 더 전달될 수 있습니다.
<?php namespace App\Http\Middleware; use Closure;use Illuminate\Http\Request;use Illuminate\Support\Facades\Auth;use Symfony\Component\HttpFoundation\Response; class AuthenticateOnceWithBasicAuth{ /** * 들어오는 요청 처리. * * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */ public function handle(Request $request, Closure $next): Response { return Auth::onceBasic() ?: $next($request); } }
다음으로, 미들웨어를 경로에 연결합니다.
Route::get('/api/user', function () { // 인증된 사용자만 이 경로에 액세스할 수 있습니다...})->middleware(AuthenticateOnceWithBasicAuth::class);
로그아웃
애플리케이션에서 사용자를 수동으로 로그아웃하려면 Auth 파사드에서 제공하는 logout 메서드를 사용할 수 있습니다. 이렇게 하면 후속 요청이 인증되지 않도록 사용자 세션에서 인증 정보가 제거됩니다.
logout 메서드를 호출하는 것 외에도 사용자 세션을 무효화하고 CSRF 토큰을 재생성하는 것이 좋습니다. 사용자를 로그아웃한 후에는 일반적으로 사용자를 애플리케이션 루트로 리디렉션합니다.
use Illuminate\Http\Request;use Illuminate\Http\RedirectResponse;use Illuminate\Support\Facades\Auth; /** * 사용자를 애플리케이션에서 로그아웃합니다. */public function logout(Request $request): RedirectResponse{ Auth::logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return redirect('/');}
다른 장치에서 세션 무효화
Laravel은 현재 장치에서 세션을 무효화하지 않고 다른 장치에서 활성 상태인 사용자 세션을 무효화하고 "로그아웃"하는 메커니즘도 제공합니다. 이 기능은 일반적으로 사용자가 비밀번호를 변경하거나 업데이트할 때 다른 장치의 세션을 무효화하면서 현재 장치를 인증된 상태로 유지하려는 경우에 사용됩니다.
시작하기 전에 세션 인증을 받아야 하는 경로에 Illuminate\Session\Middleware\AuthenticateSession 미들웨어가 포함되어 있는지 확인해야 합니다. 일반적으로 이 미들웨어는 애플리케이션의 대부분의 경로에 적용될 수 있도록 경로 그룹 정의에 배치해야 합니다. 기본적으로 AuthenticateSession 미들웨어는 auth.session 미들웨어 별칭을 사용하여 경로에 연결할 수 있습니다.
Route::middleware(['auth', 'auth.session'])->group(function () { Route::get('/', function () { // ... });});
그런 다음 Auth 파사드에서 제공하는 logoutOtherDevices 메서드를 사용할 수 있습니다. 이 메서드를 사용하려면 사용자가 현재 비밀번호를 확인해야 하며, 애플리케이션은 입력 양식을 통해 이를 수락해야 합니다.
use Illuminate\Support\Facades\Auth; Auth::logoutOtherDevices($currentPassword);
logoutOtherDevices 메서드가 호출되면 사용자의 다른 세션이 완전히 무효화되어 이전에 인증되었던 모든 가드에서 "로그아웃"됩니다.
비밀번호 확인
애플리케이션을 빌드하는 동안, 작업을 수행하기 전에 또는 사용자를 애플리케이션의 중요한 영역으로 리디렉션하기 전에 사용자가 비밀번호를 확인해야 하는 경우가 있습니다. Laravel에는 이 프로세스를 쉽게 만드는 기본 제공 미들웨어가 포함되어 있습니다. 이 기능을 구현하려면 두 개의 경로를 정의해야 합니다. 하나는 사용자에게 비밀번호 확인을 요청하는 보기를 표시하는 경로이고, 다른 하나는 비밀번호가 유효한지 확인하고 사용자를 의도한 대상으로 리디렉션하는 경로입니다.
다음 문서는 Laravel의 비밀번호 확인 기능과 직접 통합하는 방법을 설명합니다. 그러나 더 빠르게 시작하고 싶다면 Laravel 애플리케이션 스타터 키트에 이 기능에 대한 지원이 포함되어 있습니다!
구성
비밀번호를 확인한 후 사용자는 3시간 동안 다시 비밀번호를 확인하라는 메시지를 받지 않습니다. 그러나 애플리케이션의 config/auth.php 구성 파일 내에서 password_timeout 구성 값의 값을 변경하여 사용자가 비밀번호를 다시 묻는 메시지를 받기 전의 시간을 구성할 수 있습니다.
라우팅
비밀번호 확인 양식
먼저, 사용자에게 비밀번호 확인을 요청하는 보기를 표시하는 경로를 정의합니다.
Route::get('/confirm-password', function () { return view('auth.confirm-password');})->middleware('auth')->name('password.confirm');
예상대로 이 경로에서 반환되는 보기에는 password 필드를 포함하는 양식이 있어야 합니다. 또한 사용자가 애플리케이션의 보호된 영역에 들어가고 있으며 비밀번호를 확인해야 한다는 것을 설명하는 텍스트를 보기에 자유롭게 포함할 수 있습니다.
비밀번호 확인
다음으로, "비밀번호 확인" 보기에서 양식 요청을 처리하는 경로를 정의합니다. 이 경로는 비밀번호 유효성을 검사하고 사용자를 의도한 대상으로 리디렉션하는 역할을 합니다.
use Illuminate\Http\Request;use Illuminate\Support\Facades\Hash;use Illuminate\Support\Facades\Redirect; Route::post('/confirm-password', function (Request $request) { if (! Hash::check($request->password, $request->user()->password)) { return back()->withErrors([ 'password' => ['제공된 비밀번호가 기록과 일치하지 않습니다.'] ]); } $request->session()->passwordConfirmed(); return redirect()->intended();})->middleware(['auth', 'throttle:6,1']);
계속 진행하기 전에 이 경로를 자세히 살펴보겠습니다. 먼저 요청의 password 필드가 실제로 인증된 사용자의 비밀번호와 일치하는지 확인합니다. 비밀번호가 유효하면 사용자가 비밀번호를 확인했음을 Laravel 세션에 알려야 합니다. passwordConfirmed 메서드는 사용자가 마지막으로 비밀번호를 확인한 시간을 확인하는 데 Laravel이 사용할 수 있는 타임스탬프를 사용자 세션에 설정합니다. 마지막으로 사용자를 의도한 대상으로 리디렉션할 수 있습니다.
경로 보호
최근 비밀번호 확인이 필요한 작업을 수행하는 모든 경로에 password.confirm 미들웨어가 할당되었는지 확인해야 합니다. 이 미들웨어는 Laravel의 기본 설치에 포함되어 있으며 사용자가 비밀번호를 확인한 후 해당 위치로 리디렉션될 수 있도록 사용자의 의도한 대상을 세션에 자동으로 저장합니다. 사용자의 의도한 대상을 세션에 저장한 후 미들웨어는 사용자를 password.confirm 명명된 경로로 리디렉션합니다.
Route::get('/settings', function () { // ...})->middleware(['password.confirm']); Route::post('/settings', function () { // ...})->middleware(['password.confirm']);
사용자 정의 가드 추가
Auth 파사드에서 extend 메서드를 사용하여 사용자 정의 인증 가드를 정의할 수 있습니다. extend 메서드에 대한 호출은 서비스 공급자 내에 배치해야 합니다. Laravel에는 이미 AppServiceProvider가 제공되므로 해당 공급자에 코드를 배치할 수 있습니다.
<?php namespace App\Providers; use App\Services\Auth\JwtGuard;use Illuminate\Contracts\Foundation\Application;use Illuminate\Support\Facades\Auth;use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider{ // ... /** * 모든 애플리케이션 서비스를 부트스트랩합니다. */ public function boot(): void { Auth::extend('jwt', function (Application $app, string $name, array $config) { // Illuminate\Contracts\Auth\Guard의 인스턴스 반환... return new JwtGuard(Auth::createUserProvider($config['provider'])); }); }}
위의 예에서 볼 수 있듯이 extend 메서드에 전달된 콜백은 Illuminate\Contracts\Auth\Guard의 구현을 반환해야 합니다. 이 인터페이스에는 사용자 정의 가드를 정의하기 위해 구현해야 하는 몇 가지 메서드가 포함되어 있습니다. 사용자 정의 가드가 정의되면 auth.php 구성 파일의 guards 구성에서 가드를 참조할 수 있습니다.
'guards' => [ 'api' => [ 'driver' => 'jwt', 'provider' => 'users', ],],
클로저 요청 가드
사용자 정의 HTTP 요청 기반 인증 시스템을 구현하는 가장 간단한 방법은 Auth::viaRequest 메서드를 사용하는 것입니다. 이 메서드를 사용하면 단일 클로저를 사용하여 인증 프로세스를 빠르게 정의할 수 있습니다.
시작하려면 애플리케이션의 AppServiceProvider의 boot 메서드 내에서 Auth::viaRequest 메서드를 호출합니다. viaRequest 메서드는 첫 번째 인수로 인증 드라이버 이름을 수락합니다. 이 이름은 사용자 정의 가드를 설명하는 모든 문자열일 수 있습니다. 메서드에 전달된 두 번째 인수는 들어오는 HTTP 요청을 수신하고 사용자 인스턴스 또는 인증에 실패한 경우 null을 반환하는 클로저여야 합니다.
use App\Models\User;use Illuminate\Http\Request;use Illuminate\Support\Facades\Auth; /** * 모든 애플리케이션 서비스를 부트스트랩합니다. */public function boot(): void{ Auth::viaRequest('custom-token', function (Request $request) { return User::where('token', (string) $request->token)->first(); });}
사용자 정의 인증 드라이버가 정의되면 auth.php 구성 파일의 guards 구성 내에서 드라이버로 구성할 수 있습니다.
'guards' => [ 'api' => [ 'driver' => 'custom-token', ],],
마지막으로, 경로에 인증 미들웨어를 할당할 때 가드를 참조할 수 있습니다.
Route::middleware('auth:api')->group(function () { // ...});
사용자 정의 사용자 공급자 추가
사용자를 저장하는 데 기존의 관계형 데이터베이스를 사용하지 않는 경우 사용자 정의 인증 사용자 공급자로 Laravel을 확장해야 합니다. Auth 파사드에서 provider 메서드를 사용하여 사용자 정의 사용자 공급자를 정의합니다. 사용자 공급자 확인자는 Illuminate\Contracts\Auth\UserProvider의 구현을 반환해야 합니다.
<?php namespace App\Providers; use App\Extensions\MongoUserProvider;use Illuminate\Contracts\Foundation\Application;use Illuminate\Support\Facades\Auth;use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider{ // ... /** * 모든 애플리케이션 서비스를 부트스트랩합니다. */ public function boot(): void { Auth::provider('mongo', function (Application $app, array $config) { // Illuminate\Contracts\Auth\UserProvider의 인스턴스 반환... return new MongoUserProvider($app->make('mongo.connection')); }); }}
provider 메서드를 사용하여 공급자를 등록한 후에는 auth.php 구성 파일에서 새 사용자 공급자로 전환할 수 있습니다. 먼저 새 드라이버를 사용하는 provider를 정의합니다.
'providers' => [ 'users' => [ 'driver' => 'mongo', ],],
마지막으로 guards 구성에서 이 공급자를 참조할 수 있습니다.
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ],],
사용자 공급자 계약
Illuminate\Contracts\Auth\UserProvider 구현은 MySQL, MongoDB 등과 같은 지속적 스토리지 시스템에서 Illuminate\Contracts\Auth\Authenticatable 구현을 가져오는 역할을 합니다. 이 두 인터페이스를 통해 사용자 데이터가 저장되는 방식이나 인증된 사용자를 나타내는 데 사용되는 클래스 유형에 관계없이 Laravel 인증 메커니즘이 계속 작동할 수 있습니다.
Illuminate\Contracts\Auth\UserProvider 계약을 살펴보겠습니다.
<?php namespace Illuminate\Contracts\Auth; interface UserProvider{ public function retrieveById($identifier); public function retrieveByToken($identifier, $token); public function updateRememberToken(Authenticatable $user, $token); public function retrieveByCredentials(array $credentials); public function validateCredentials(Authenticatable $user, array $credentials); public function rehashPasswordIfRequired(Authenticatable $user, array $credentials, bool $force = false);}
retrieveById 함수는 일반적으로 MySQL 데이터베이스의 자동 증가 ID와 같이 사용자를 나타내는 키를 수신합니다. ID와 일치하는 Authenticatable 구현을 검색하여 메서드에서 반환해야 합니다.
retrieveByToken 함수는 고유한 $identifier와 "기억하기" $token으로 사용자를 검색합니다. 일반적으로 데이터베이스의 remember_token과 같은 열에 저장됩니다. 이전 메서드와 마찬가지로 이 메서드에서 일치하는 토큰 값을 가진 Authenticatable 구현을 반환해야 합니다.
updateRememberToken 메서드는 $user 인스턴스의 remember_token을 새 $token으로 업데이트합니다. 성공적인 "기억하기" 인증 시도 또는 사용자가 로그아웃할 때 사용자에게 새 토큰이 할당됩니다.
retrieveByCredentials 메서드는 애플리케이션으로 인증을 시도할 때 Auth::attempt 메서드에 전달된 자격 증명 배열을 수신합니다. 그런 다음 메서드는 해당 자격 증명과 일치하는 사용자에 대해 기본 지속적 스토리지를 "쿼리"해야 합니다. 일반적으로 이 메서드는 $credentials['username'] 값과 일치하는 "username"이 있는 사용자 레코드를 검색하는 "where" 조건으로 쿼리를 실행합니다. 이 메서드는 Authenticatable의 구현을 반환해야 합니다. 이 메서드는 비밀번호 유효성 검사 또는 인증을 시도해서는 안 됩니다.
validateCredentials 메서드는 사용자를 인증하기 위해 주어진 $user를 $credentials와 비교해야 합니다. 예를 들어 이 메서드는 일반적으로 Hash::check 메서드를 사용하여 $user->getAuthPassword() 값을 $credentials['password'] 값과 비교합니다. 이 메서드는 비밀번호가 유효한지 여부를 나타내는 true 또는 false를 반환해야 합니다.
rehashPasswordIfRequired 메서드는 필요한 경우 주어진 $user의 비밀번호를 다시 해시해야 합니다. 예를 들어 이 메서드는 일반적으로 Hash::needsRehash 메서드를 사용하여 $credentials['password'] 값을 다시 해시해야 하는지 여부를 확인합니다. 비밀번호를 다시 해시해야 하는 경우 메서드는 Hash::make 메서드를 사용하여 비밀번호를 다시 해시하고 기본 지속적 스토리지에서 사용자 레코드를 업데이트해야 합니다.
인증 가능 계약
이제 UserProvider의 각 메서드를 살펴보았으므로 Authenticatable 계약을 살펴보겠습니다. 사용자 공급자는 retrieveById, retrieveByToken 및 retrieveByCredentials 메서드에서 이 인터페이스의 구현을 반환해야 합니다.
<?php namespace Illuminate\Contracts\Auth; interface Authenticatable{ public function getAuthIdentifierName(); public function getAuthIdentifier(); public function getAuthPasswordName(); public function getAuthPassword(); public function getRememberToken(); public function setRememberToken($value); public function getRememberTokenName();}
이 인터페이스는 간단합니다. getAuthIdentifierName 메서드는 사용자의 "기본 키" 열의 이름을 반환해야 하고 getAuthIdentifier 메서드는 사용자의 "기본 키"를 반환해야 합니다. MySQL 백엔드를 사용하는 경우 사용자의 레코드에 할당된 자동 증가 기본 키일 가능성이 높습니다. getAuthPasswordName 메서드는 사용자의 비밀번호 열 이름을 반환해야 합니다. getAuthPassword 메서드는 사용자의 해시된 비밀번호를 반환해야 합니다.
이 인터페이스를 통해 인증 시스템은 사용 중인 ORM 또는 스토리지 추상화 계층에 관계없이 모든 "사용자" 클래스에서 작동할 수 있습니다. 기본적으로 Laravel에는 이 인터페이스를 구현하는 app/Models 디렉터리에 App\Models\User 클래스가 포함되어 있습니다.
자동 비밀번호 재해시
Laravel의 기본 비밀번호 해시 알고리즘은 bcrypt입니다. bcrypt 해시의 "작업 요소"는 애플리케이션의 config/hashing.php 구성 파일 또는 BCRYPT_ROUNDS 환경 변수를 통해 조정할 수 있습니다.
일반적으로 CPU / GPU 처리 능력이 향상됨에 따라 시간 경과에 따라 bcrypt 작업 요소를 늘려야 합니다. 애플리케이션의 bcrypt 작업 요소를 늘리면 사용자가 Laravel의 스타터 키트를 통해 애플리케이션으로 인증하거나 attempt 메서드를 통해 수동으로 사용자를 인증할 때 Laravel이 사용자 비밀번호를 정상적으로 자동으로 다시 해시합니다.
일반적으로 자동 비밀번호 재해시는 애플리케이션을 중단시키지 않아야 합니다. 그러나 hashing 구성 파일을 게시하여 이 동작을 비활성화할 수 있습니다.
php artisan config:publish hashing
구성 파일이 게시되면 rehash_on_login 구성 값을 false로 설정할 수 있습니다.
'rehash_on_login' => false,
이벤트
Laravel은 인증 프로세스 중에 다양한 이벤트를 발생시킵니다. 다음 이벤트에 대해 리스너를 정의할 수 있습니다.
| 이벤트 이름 |
|---|
Illuminate\Auth\Events\Registered |
Illuminate\Auth\Events\Attempting |
Illuminate\Auth\Events\Authenticated |
Illuminate\Auth\Events\Login |
Illuminate\Auth\Events\Failed |
Illuminate\Auth\Events\Validated |
Illuminate\Auth\Events\Verified |
Illuminate\Auth\Events\Logout |
Illuminate\Auth\Events\CurrentDeviceLogout |
Illuminate\Auth\Events\OtherDeviceLogout |
Illuminate\Auth\Events\Lockout |
Illuminate\Auth\Events\PasswordReset |