Laravel 08. Authentication System

@ 시간이 된다면 blade 에 @push @stack 설명할것.
Laravel은 기본적으로 회원, 로그인에 대한 정보를
- users 테이블
- User 모델
- session 기반 로그인
으로 처리하고 있습니다.
기본으로 제공하는 컬럼은
- name
- password
Anthentication
Index ( with bootstrap )
resources/views/index.blade.php
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap demo</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
</head>
<body>
<div class="container mt-5 col-lg-3 col-md-4 col-sm-12 mx-auto">
<div class="row">
<div class="col text-end">
<div class="">
Welcome Guest
</div>
</div>
</div>
<div class="row text-center mt-5">
<h1>
Index Page
</h1>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"></script>
</body>
</html>
php artisan make:controller IndexController
app/http/Controller/IndexController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class IndexController extends Controller
{
/**
* Handle the incoming request.
*/
public function index(Request $request)
{
//
return view('index');
}
}
Route
routes/web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\IndexController;
Route::get('/', [IndexController::class, 'index'])->name('index');
http://127.0.0.1:8000

Register
example https://getbootstrap.com/docs/5.3/forms/overview/
View
resources/views/member/register.blade.php
<form method="post" action="{{ route('signup') }}" autocomplete="off">
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" name="name">
</div>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" name="email" aria-describedby="emailHelp">
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
Controller
php artisan make:controller UserController
app/http/Controller/UserController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
//
public function signup_form(){
return view('member.register');
}
}
Route
routes/web.php
use App\Http\Controllers\UserController;
Route::get('/register', [UserController::class, 'signup_form'])->name('signup_form');
Route::post('/register', [UserController::class, 'signup_submit'])->name('signup');
http://127.0.0.1:8000/register

app/http/Controller/UserController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
class UserController extends Controller
{
//
public function signup_form(){
return view('member.register');
}
public function signup_submit(Request $request) {
// $request->validate([
// 'name' => 'required|min:2|max:20',
// 'email' => 'required|email',
// 'password' => 'required|min:8',
// ]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
if($user) {
return redirect()->route('index')->with('success', 'User created successfully');
} else {
return redirect()->route('register')->with('error', 'User creation failed');
}
}
}
go submit!!
Login
resources/views/member/login.blade.php
<form method="post" action="{{ route('signin') }}" autocomplete="off">
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" name="email" aria-describedby="emailHelp">
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
routes/web.php
..
Route::get('/login', [UserController::class, 'signin_form'])->name('login');
Route::post('/login', [UserController::class, 'signin_submit'])->name('signin');
app/http/Controller/UserController.php
use Illuminate\Support\Facades\Auth;
public function signin_form()
{
return view('member.login');
}
public function signin_submit(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$user = User::where('email', $request->email)->first();
if($user){
// Hash::make($request->password),
// if ($user && Hash::check($request->password, $user->password)) {
// // successful login
// return redirect()->route('index')->with('success', 'Login successful');
// } else {
// // login failed
// return redirect()->route('login')->with('error', 'Invalid email or password');
// }
if(Auth::attempt([
'email' => $request->email,
'password' => $request->password
])){
return redirect('/');
}
} else {
return redirect()->route('login')->with('error', 'Invalid email or password');
}
}
or
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
return redirect()->intended('/');
}
Status
IndexController.php
use Illuminate\Support\Facades\Auth;
if(Auth::check()){
$user = Auth::user();
} else {
$user = [];
}
return view('index', [
'user' => isset($user) ? $user : null
]);
resources/views/index.blade.php
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap demo</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
</head>
<body>
<div class="container mt-5 col-lg-3 col-md-4 col-sm-12 mx-auto">
<div class="row">
<div class="col text-end">
@if(isset($user) && $user != null)
<div class="">Welcome {{ $user['name'] }} </div>
@else
<div class="">Welcome Guest
<a href="{{ route('login') }}">Login </a>
|
<a href="{{ route('register') }}">Register </a>
</div>
@endif
</div>
</div>
<div class="row text-center">
<h1>
Index Page
</h1>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"></script>
</body>
</html>
logout
resources/views/index.blade.php
<div class="">Welcome {{ $user['name'] }} <a href="{{ route('logout') }}" class="">Logout</a></div>
routes/web.php
Route::get('/logout', [UserController::class, 'signout'])->name('logout');
app/http/Controller/UserController.php
public function signout(Request $request){
//auth()->logout();
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect()->route('index');
}
Middleware
“사용자의 요청이 컨트롤러에 도착하기 전에 중간에서 검사하는 기능”

이럴때 사용합니다.
- 로그인 여부 확인
- 관리자 권한 확인
- API 토큰 확인
- 로그 기록
Laravel 기본 middleware
auth
로그인한 사용자만 허용
routes/web.php
Route::middleware('auth')->group(function () {
Route::get('/dashboard');
});
** 로그인을 안했다면 로그인페이지로 이동합니다.
이것은 아래에 설정되었습니다.
vendor/laravel/framework/src/Illuminate/Foundation/Configuration/ApplicationBuilder.php
public function withMiddleware(?callable $callback = null)
{
$this->app->afterResolving(HttpKernel::class, function ($kernel) use ($callback) {
$middleware = (new Middleware)
->redirectGuestsTo(fn () => route('login'));
.....
guest
로그인 안한 사용자만 허용
Route::middleware('guest')->group(function () {
Route::get('/login');
});
로그인여부
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class AdminMiddleware
{
/**
* Handle an incoming request.
*
* @param Closure(Request): (Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
// your codes....
if (!auth()->check()) {
return redirect('/login');
}
return $next($request);
}
}
관리자 확인
관리자구분을 위해서 type 컬럼을 하나 추가하고 기본은 9 가 입력되게 한다.
php artisan make:migration add_type_to_users
database/migrations/2026_xx_xx_xxxxxx_add_type_to_users.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
//
$table->integer('type')->default(9)->comment('1: admin, 9: user');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
//
$table->dropColumn('type');
});
}
};
php artisan migrate
** 관리자 계정만들기
1) admin 이라는 아이디로 가입합니다.
2) 나중에는 관리자가 user 의 type을 변경하는 기능을 만들기로 하고, 지금은 수동으로 type=1 로 변경한다.
php artisan make:middleware AdminMiddleware
AdminMiddleware
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class AdminMiddleware
{
/**
* Handle an incoming request.
*
* @param Closure(Request): (Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
// 관리자
if ( !auth()->check() || auth()->user()->type != 1 ) {
return redirect('/');
}
return $next($request);
}
}
Laravel 10 이하에서는 app/Http/Kernel.php
이후에는 bootstrap/app.php 에 통합
bootstrap/app.php
<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware): void {
// 미들웨어 별칭 등록 (기존 routeMiddleware 역할)
$middleware->alias([
'admin' => \App\Http\Middleware\AdminMiddleware::class,
]);
})
->withExceptions(function (Exceptions $exceptions): void {
//
})->create();
route/web.php
use App\Http\Controllers\AdminController;
Route::get('/admin', [AdminController::class, 'index'])->name('admin.index')->middleware('admin');
controller
php artisan make:controller AdminController
app/Http/Controllers/AdminController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
class AdminController extends Controller
{
//
public function index(){
//Gate::authorize('admin-only');
return view('admin.index');
}
}
Gate 를 이용해서 처리할 수도 있습니다.
Gate는 사용자에게 특정 작업을 수행할 권한이 있는지 확인하는 가장 빠르고 직관적인 방법
다만, Gate는 이미 들어온 요청에서 특정행동 권한을 판단할때 많이 사용합니다.
app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Gate;
use App\Models\User;
public function boot(): void
{
// 'admin'이라는 이름의 게이트 정의
Gate::define('admin-only', function (User $user) {
return $user->type === 1; // true or false
});
}
1) controller 를 이용하는 방법
Gate::authorize('admin-only');
// 이 한줄만으로 false 면 403 에러
2) route 를 이용하는 방법
Route::middleware('auth')->group(function () {
Route::get('/admin', [AdminController::class, 'index'])->name('admin.index')->middleware('can:admin-only');
});
3) view 에서 이용방법
<div class="">Welcome {{ $user['name'] }}
@can('admin-only')
<a href="{{ route('admin.index') }}" class="">Admin Index</span>
@endcan
<a href="{{ route('signout') }}" class="">Logout</span>
</div>