[Laravel] 4장 사용자 인증 및 권한 관리

1. 인증 기능 설정

라라벨 8 이상에서는 laravel/ui 패키지를 사용해 인증 기능을 쉽게 설정합니다. 아래 명령어로 패키지를 설치하고 php로 인증 스캐폴딩을 생성합니다.

composer require laravel/ui
php artisan ui bootstrap --auth
npm install
npm run dev

 

 


2.데이터베이스 설정

.env 파일을 열어 데이터페이스를 설정합니다.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_username
DB_PASSWORD=your_password

 

사용자 테이블을 생성하기 위해 마이그레이션을 실행합니다.

php artisan migrate

 

이제 기본적인 로그인 및 회원가입 기능이 구현되었습니다. /register 및 /login 경로로 접근해 회원가입 및 로그인을 시도할 있습니다.


3. 권한 관리 구현

권한 관리에는 여러 방법이 있지만, 여기서는 간단한 역할 기반 접근 제어(RBAC)를 구현합니다. 먼저 Role 모델을 생성합니다.

php artisan make:model Role -m

 

Role 모델을 다음과 같이 수정합니다.

// app/Models/Role.php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
    use HasFactory;

    protected $fillable = ['name'];

    public function users()
    {
        return $this->hasMany(User::class);
    }
}

 

User 모델에 role() 메서드를 추가합니다.

// app/Models/Role.php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
    use HasFactory;

    protected $fillable = ['name'];

    public function users()
    {
        return $this->hasMany(User::class);
    }
}

 

user 모델에 role() 메서드를 추가합니다.

// app/Models/User.php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use HasFactory, Notifiable;

    protected $fillable = ['name', 'email', 'password'];

    public function role()
    {
        return $this->belongsTo(Role::class);
    }
}

 

마이그레이션 파일을 열고 역할 테이블을 정의합니다.

// database/migrations/xxxx_xx_xx_create_roles_table.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()
    {
        Schema::create('roles', function (Blueprint $table) {
            $table->id();
            $table->string('name')->unique();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('roles');
    }
};

 

users 테이블에 role_id 컬럼을 추가하는 마이그레이션도 필요합니다.

php artisan make:migration add_role_id_to_users_table --table=users

 

마이그레이션 파일을 수정합니다.

// database/migrations/xxxx_xx_xx_add_role_id_to_users_table.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()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->foreignId('role_id')->constrained()->nullable()->after('id');
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropForeign(['role_id']);
            $table->dropColumn("role_id");
        });
    }
};

 

php 마이그레이션을 실행합니다.

php artisan migrate

 

시드 파일을 생성해 기본 역할을 추가하고 RolesTableSeeder를 수정합니다.

php artisan make:seeder RolesTableSeeder
public function run(): void
{
       DB::table("roles")->Insert([
        ["name" => "admin"],
        ["name" => "user"]
       ])
}

 

마이그레이션 후 시더를 실행합니다.

php artisan db:seed --class=RolesTableSeeder

 

회원가입 시 역할을 부여하는 로직을 추가합니다. RegisterController를 수정합니다.

protected function create(array $data)
{
    $user = User::create([
        'name' => $data['name'],
        'email' => $data['email'],
        'password' => Hash::make($data['password']),
    ]);

    // 기본 역할 부여 (예: 모든 신규 사용자는 'user' 역할)
    $user->role()->associate(Role::where('name', 'user')->first());
    $user->save();

    return $user;
}

 

이제 미들웨어를 만들어 특정 경로에 대한 접근을 제어합니다.

php artisan make:middleware CheckRole

 

CheckRole 미들웨어를 다음과 같이 수정합니다.

public function handle(Request $request, Closure $next, $role)
{
       if(auth()->check() && auth()->user()->role->name === $role) {
           return $next($request);
       }

       return redirect('/home')->with('error', '권한이 없습니다');
}

 

app/Httl/Kernel.php에 미들웨어를 등록합니다.

protected $routeMiddleware = [
    'role' => \App\Http\Middleware\CheckRole::class,
];

 

라우트에서 특정 역할을 가진 사용자만 접근할 수 있도록 설정합니다.

Route::group(['middleware' => ['role:admin']], function() {
    Route::get('/admin', [AdminController::class, 'index']);
});

 

이제 /register에서 회원가입을 하고 /login에서 로그인하여, 역할에 접근할 수 있는지 테스트 해봅니다


4. 프로필 띄우기

라라벨에서 로그인 후 사용자 프로필을 표시하는 방법을 설명하겠습니다. routes/web.php 파일에 사용자 프로필을 표시할 라우트를 추가합니다.

use App\Http\Controllers\ProfileController;

Route::get('/profile', [ProfileController::class, 'show'])->middleware('auth');

 

프로필 정보를 처리할 컨트롤러를 생성합니다.

php artisan make:controller ProfileController
// app/Http/Controllers/ProfileController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class ProfileController extends Controller
{
    public function show() 
    {
        $user = Auth::user(); // 현재 로그인한 사용자 정보 가져오기
        return view('profile.show', compact('user'));
    }
}

 

resources/views/profile 디렉토리를 생성하고, show.blade.php 파일을 생성합니다.

mkdir resources/views/profile
touch resources/views/profile/show.blade.php

 

show.blade.php 파일을 다음과 같이 작성합니다.

@extends('layouts.app')

@section('content')
<div class="container">
    <h1>내 프로필</h1>
    <ul>
        <li><strong>이름:</strong> {{ $user->name }}</li>
        <li><strong>이메일:</strong> {{ $user->email }}</li>
        <li><strong>가입일:</strong> {{ $user->created_at->format('Y-m-d') }}</li>
    </ul>

    <!-- 로그아웃 폼 -->
    <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: inline;">
        @csrf
        <button type="submit" class="btn btn-danger">로그아웃</button>
    </form>
</div>
@endsection

 

네비게이션 바에 프로필 링크를 추가하여 사용자가 쉽게 접근할 수 있도록 합니다. resources/views/layouts/app.blade.php 파일을 열고, 로그인한 사용자를 위한 프로필 링크를 추가합니다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>내 애플리케이션</title>
    <link rel="stylesheet" href="{{ asset('css/app.css') }}">
</head>
<body>
    <div class="container">
        @yield('content')
    </div>
</body>
</html>

 

로그아웃시 리다이렉트 할 수 있도록 AuthenticatedSessionController를 생성합니다.

php artisan make:controller Auth/AuthenticatedSessionController

 

app/Http/Controllers/Auth/AuthenticatedSessionController.php 파일을 열고 다음과 같이 작성합니다.

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class AuthenticatedSessionController extends Controller
{
    public function destroy(Request $request)
    {
        Auth::logout();

        return redirect('/'); // 로그아웃 후 리다이렉션
        
    }
}

 

routes/web.php 파일에서 로그아웃 라우트가 올바르게 설정되어 있는지 확인합니다.

use App\Http\Controllers\Auth\AuthenticatedSessionController;

// ...

Route::post('/logout', [AuthenticatedSessionController::class, 'destroy'])->name('logout');

 

 

GitHub - Koras02/laravel-bloging

Contribute to Koras02/laravel-bloging development by creating an account on GitHub.

github.com

 

LIST