개발/Laravel

[Laravel AtoZ] 1. 로그인 추가하기

희묭 2024. 4. 15. 10:25

로그인 사전준비

로그인 추가하기

라라벨에서는 로그인을 만드는 방법으로 스타터킷(Breeze, Jetstream) 을 사용하는것을 추천합니다

그러나 디자인적인 부분이나 기능을 커스터마이징하는 경우 스타터킷의 틀에 맞춰서 변경해야되는 경우가 발생하기에 직접 구현하는 쪽으로 진행하겠습니다.

Laravel Breeze : tailwind 스타일을 적용한 간단한 인증구현
Laravel Jetstream : Livewire와 Inertia 를 지원하는 강력한 인증구현

 

Fortify

포터파이에서 회원가입, 유저정보변경, 비밀번호변경 등의 기본적인 인증 백앤드를 구현해놓았기에

우리는 편하게 인증서비스를 만들수 있습니다, 물론 만들어진 기능을 다 쓸필요는 없습니다.

composer require laravel/fortify
php artisan fortify:install

 

Livewire

라이브와이어는 라라벨에서 쉽게 SPA 를 구현할수 있도록 도와주는 프론트프레임워크입니다.

Vue 와 React 를 사용하여 방대한 Javascript진영의 자료를 활용할수도 있으나 라라벨과 가장 궁합이 좋은것은 Blade와 Livewire입니다.

아래와 같이 간단히 설치가능하며 레이아웃도 생성해줍니다

composer require livewire/livewire
php artisan livewire:layout

 

/resources/views/layouts/app.blade.php 에서 vite css 를 사용할수 있도록 아래와같이 추가해줍니다

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        {{-- add vite css --}}
        @vite('resources/css/app.css')

        <title>{{ $title ?? 'Page Title' }}</title>
    </head>
    <body>
        {{ $slot }}
    </body>
</html>

 

/resources/css/app.css 에서 회원가입과 로그인에 사용할 css를 만들어줍니다 (create by gpt)

body {
    font-family: Arial, sans-serif;
    background-color: #f9f9f9;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}
.container {
    background-color: #fff;
    padding: 40px;
    border-radius: 5px;
    box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.1);
    max-width: 400px;
    width: 100%;
    text-align: center;
}
.form-group {
    margin-bottom: 20px;
    text-align: left;
}
.form-group label {
    display: block;
    font-weight: bold;
    margin-bottom: 5px;
    color: #666;
}
.form-group input {
    width: 100%;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
    font-size: 16px;
}
.form-group button {
    width: 100%;
    padding: 12px;
    background-color: #007bff;
    color: #fff;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    font-size: 16px;
    transition: background-color 0.3s;
}
.form-group button:hover {
    background-color: #0056b3;
}

회원가입 페이지 생성

라이브와이어 페이지를 생성하고 라우트에 연결합니다

php artisan make:livewire UserCreate

 

/routes/web.php 에 라이브와이어로 생성된 UserCreate 페이지를 등록합니다

use App\Livewire\UserCreate;

...

Route::get('/register', UserCreate::class)->name("register");

 

생성된 라이브이와이어 컴포넌트는 컴포넌트 본체와 뷰영역으로 나뉘어집니다.

/app/Livewire 에서 컴포넌트를 작성할수 있습니다

/resources/views/livewire 에서 컴포넌트의 뷰영역을 작성할수 있습니다

 

우선 컴포넌트를 아래와같이 작성합니다 (/app/Livewire/UserCreate.php)

<?php

namespace App\Livewire;

use App\Actions\Fortify\CreateNewUser;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;
#[Layout('components.layouts.app')]
#[Title('생성')]
class UserCreate extends Component
{
    public $name = '';
    public $email = '';
    public $password = '';
    public $passwordConfirm = '';

    private CreateNewUser $createNewUser;

    public function boot (CreateNewUser $createNewUser): void
    {
        $this->createNewUser = $createNewUser;
    }

    public function create()
    {
        $input = array(
            'name'=>$this->name,
            'email'=>$this->email,
            'password'=>$this->password,
            'password_confirmation'=>$this->passwordConfirm
        );

        $this->createNewUser->create($input);

        $this->redirect("/");
    }

    public function render()
    {
        return view('livewire.user-create');
    }
}

 

그리고 뷰영역을 아래와 같이 작성합니다 (resources/views/livewire/user-create.blade.php)

<div class="container">
    <h2>회원가입</h2>
    <div class="form-group">
        <label for="name">이름</label>
        <input x-model="$wire.name" type="text" id="name" name="name">
    </div>
    @error('name') <label style="color: red">{{$message}}</label> @enderror
    <div class="form-group">
        <label for="email">이메일</label>
        <input x-model="$wire.email" type="text" id="email" name="email">
    </div>
    @error('email') <label style="color: red">{{$message}}</label> @enderror
    <div class="form-group">
        <label for="password">비밀번호</label>
        <input x-model="$wire.password" type="password" id="password" name="password">
    </div>
    @error('password') <label style="color: red">{{$message}}</label> @enderror
    <div class="form-group">
        <label for="confirm_password">비밀번호 확인</label>
        <input x-model="$wire.passwordConfirm" type="password" id="confirm_password" name="confirm_password" >
    </div>
    @error('passwordConfirm') <label style="color: red">{{$message}}</label> @enderror
    <div class="form-group">
        <button @click="$wire.create()">회원가입</button>
    </div>
</div>

로그인 페이지 생성

회원가입과 같은 작업을 진행합니다

php artisan make:livewire UserLogin
use App\Livewire\UserCreate;
use App\Livewire\UserLogin;

...

Route::get('/register', UserCreate::class)->name("register");
Route::get('/login', UserLogin::class)->name("login");

 

컴포넌트를 아래와같이 작성합니다 (/app/Livewire/UserLogin.php)

<?php

namespace App\Livewire;

use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Layout('components.layouts.app')]
#[Title('로그인')]
class UserLogin extends Component
{
    public $email = '';
    public $password = '';

    public function login()
    {
        $input = array(
            'email'=>$this->email,
            'password'=>$this->password
        );

        Validator::make($input, [
            'email' => ['required', 'email', Rule::exists(User::class)],
            'password' => ['required']
        ])->validate();

        if (! Auth::attempt($input)){
            throw ValidationException::withMessages(['email' => trans('auth.failed'),]);
        }

        $this->redirect("/");
    }

    public function render()
    {
        return view('livewire.user-login');
    }
}

 

뷰영역을 아래와 같이 작성합니다 (resources/views/livewire/user-login.blade.php)

<div class="container">
    <h2>로그인</h2>
    <div class="form-group">
        <label for="email">이메일</label>
        <input x-model="$wire.email" type="text" id="email" name="email">
    </div>
    @error('email') <label style="color: red">{{$message}}</label> @enderror
    <div class="form-group">
        <label for="password">비밀번호</label>
        <input x-model="$wire.password" type="password" id="password" name="password">
    </div>
    @error('password') <label style="color: red">{{$message}}</label> @enderror
    <div class="form-group">
        <button @click="$wire.login()">로그인</button>
    </div>
</div>

결과보기

@vite 로 app.css 를 불러오기위해서는 번들링 과정이 필요합니다

npm install
npm run build

 

이제 서버를 기동합니다

php artisan serve

 

메인화면 상단에 Register 를 클릭하여 회원가입을 진행합니다

그후에 상단에 Login 을 클릭하여 로그인을 진행합니다

Let's try 로그인

 

그러면 메인화면 상단의 로그인, 회원가입 메뉴가 사라지고 Dashboard 가 뜨는 걸 보실수 있습니다