PHP Информация Гайд Как сделать авторизацию в личный кабинет на сайте

Andrey Markelov

Новичок
Автор темы
7
7
logo.png

Laravel — это современный PHP-фреймворк, который позволяет быстро и эффективно создавать веб-приложения. Его мощные инструменты и простая структура делают его идеальным выбором для разработки личного кабинета для вашего SAMP сервера. В этой статье мы создадим авторизацию для личного кабинета, которая будет работать с существующей базой данных SAMP сервера.

Мы настроим три страницы:
1. Главная: / — основная страница сайта.
2. Авторизация: /auth — форма для ввода никнейма и пароля.
3. Личный кабинет: /profile — страница с информацией об игроке после авторизации.

Для начала давайте установим Laravel и подготовим базовое окружение.



Установка Laravel​

1. Убедитесь, что ваш компьютер соответствует системным требованиям Laravel:
  • PHP версии 8.2 или выше
  • Composer (менеджер зависимостей PHP)

2. Скачайте Laravel с помощью Composer
Откройте терминал и выполните следующую команду, чтобы создать новый проект Laravel: composer create-project laravel/laravel samp
Здесь samp — это название папки для проекта. Вы можете указать свое.

3. Перейдите в папку проекта: cd samp

4. Настройте подключение к базе данных.
Laravel использует файл .env для хранения конфигурации. Найдите строки, отвечающие за подключение к базе данных, и укажите данные вашей SAMP базы:
.env:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=название_базы
DB_USERNAME=имя_пользователя
DB_PASSWORD=пароль

5. Запустите встроенный сервер разработки Laravel: php artisan serve
После запуска вы увидите сообщение, что сервер работает, например, на 127.0.0.1:8000. Перейдите по этой ссылке в браузере.



Настройка роутов​

Откройте файл routes/web.php, который отвечает за определение роутов вашего сайта. Добавим туда наши роуты:
web.php:
<?php

use Illuminate\Support\Facades\Route;

// Главная страница
Route::get('/', function () {
    return view('welcome'); // Страница для главной
});

// Страница авторизации
Route::get('/auth', function () {
    return view('auth'); // Отдельный шаблон для авторизации
});

// Личный кабинет
Route::get('/profile', function () {
    return view('profile'); // Страница для личного кабинета
});

Для каждого роута нам понадобятся базовые HTML-шаблоны. Создадим их в папке resources/views:
1. Главная страница.
Создайте файл resources/views/welcome.blade.php:
welcome.blade.php:
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Главная</title>
</head>
<body>
    <h1>Добро пожаловать на ваш сайт!</h1>
    <a href="/auth">Войти</a>
</body>
</html>

2. Страница авторизации. Создайте файл resources/views/auth.blade.php:
auth.blade.php:
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Авторизация</title>
</head>
<body>
    <h1>Вход в личный кабинет</h1>
    <form action="/auth" method="POST">
        @csrf
        <label for="nickname">Ник:</label>
        <input type="text" id="nickname" name="nickname" required>
        <br>
        <label for="password">Пароль:</label>
        <input type="password" id="password" name="password" required>
        <br>
        <button type="submit">Войти</button>
    </form>
</body>
</html>

3. Личный кабинет. Создайте файл resources/views/profile.blade.php:
profile.blade.php:
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Личный кабинет</title>
</head>
<body>
    <h1>Добро пожаловать в личный кабинет!</h1>
    <p>Здесь будет отображаться информация о вашем аккаунте.</p>
    <a href="/">Вернуться на главную</a>
</body>
</html>

Тестирование роутов. Теперь вы можете проверить роуты в браузере:
  • Перейдите на 127.0.0.1:8000 — главная страница.
  • Нажмите "Войти" и перейдите на 127.0.0.1:8000/auth — страница авторизации.
  • Для /profile пока просто введите 127.0.0.1:8000/profile в адресной строке. Позже мы защитим эту страницу.



Настройка модели​

Если у вас таблица называется accounts, то в Laravel рекомендуется создать модель с именем Account, чтобы придерживаться стандартов. Laravel автоматически связывает название модели во множественном числе с таблицей, если это возможно. Например:
  • Модель Account по умолчанию будет связана с таблицей accounts.
  • Модель Player будет связана с таблицей players.
Если ваше название модели совпадает с названием таблицы (во множественном числе), дополнительных настроек не требуется. Однако, если название отличается, нужно будет явно указать таблицу в модели: protected $table = 'my_users';

Если ваша таблица называется accounts — создайте модель Account: php artisan make:model Account
Если ваша таблица называется users — откройте файл app/Models/User.php и добавьте все поля в $fillable, которые будут использоваться на сайте:
User.php:
<?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 = [
        'nickname',
        'email',
        'player_money',
        'player_donate',
        'player_skin',
        'password',
    ];

    // Поля, которые скрываются при сериализации модели.
    protected $hidden = [
        'password',
    ];
}



Реализация логики авторизации​

1. Создание контроллера. Создадим контроллер для обработки роутов авторизации и личного кабинета. Назовём его AuthController: php artisan make:controller AuthController

2. Реализация методов в контроллере.
Откройте файл app/Http/Controllers/AuthController.php и реализуйте методы:

Отображение формы авторизации:
showLoginForm:
public function showLoginForm()
{
    return view('auth');
}

Обработка авторизации:
login:
public function login(Request $request)
{
    // Валидируем данные
    $request->validate([
        'nickname' => 'required|string',
        'password' => 'required|string',
    ]);

    // Получаем никнейм и пароль
    $nickname = $request->input('nickname');
    $password = $request->input('password');

    // Хэшируем пароль в MD5
    $hashedPassword = md5($password);

    // Проверяем пользователя в базе данных
    $user = User::where('nickname', $nickname)
                ->where('password', $hashedPassword)
                ->first();

    if ($user) {
        // Сохраняем пользователя в сессии
        $request->session()->put('user', $user);

        // Редирект в личный кабинет
        return redirect()->route('profile');
    }

    // Возвращаем обратно с ошибкой
    return back()->withErrors(['message' => 'Неверный никнейм или пароль']);
}

Если в вашей базе данных пароли хранятся в формате bcrypt:
login:
public function login(Request $request)
{
    // Валидируем данные
    $request->validate([
        'nickname' => 'required|string',
        'password' => 'required|string',
    ]);

    // Получаем никнейм и пароль
    $nickname = $request->input('nickname');
    $password = $request->input('password');

    // Проверяем пользователя в базе данных
    $user = User::where('nickname', $nickname)->first();

    if ($user && Hash::check($password, $user->password)) {
        // Сохраняем пользователя в сессии
        $request->session()->put('user', $user);

        // Редирект в личный кабинет
        return redirect()->route('profile');
    }

    // Возвращаем обратно с ошибкой
    return back()->withErrors(['message' => 'Неверный никнейм или пароль']);
}

Личный кабинет:
profile:
public function profile(Request $request)
{
    // Проверяем, авторизован ли пользователь
    $user = $request->session()->get('user');

    if (!$user) {
        return redirect()->route('auth.form')->withErrors(['message' => 'Сначала войдите в систему']);
    }

    return view('profile', ['user' => $user]);
}

Выход из аккаунта:
logout:
public function logout(Request $request)
{
    // Удаляем данные из сессии
    $request->session()->forget('user');

    return redirect('/');
}

AuthController.php:
<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;

class AuthController extends Controller
{
    public function showLoginForm()
    {
        return view('auth');
    }

    public function login(Request $request)
    {
        // Валидируем данные
        $request->validate([
            'nickname' => 'required|string',
            'password' => 'required|string',
        ]);

        // Получаем никнейм и пароль
        $nickname = $request->input('nickname');
        $password = $request->input('password');

        // Хэшируем пароль в MD5
        $hashedPassword = md5($password);

        // Проверяем пользователя в базе данных
        $user = User::where('nickname', $nickname)
            ->where('password', $hashedPassword)
            ->first();

        if ($user) {
            // Сохраняем пользователя в сессии
            $request->session()->put('user', $user);

            // Редирект в личный кабинет
            return redirect()->route('profile');
        }

        // Возвращаем обратно с ошибкой
        return back()->withErrors(['message' => 'Неверный никнейм или пароль']);
    }

    public function profile(Request $request)
    {
        // Проверяем, авторизован ли пользователь
        $user = $request->session()->get('user');

        if (!$user) {
            return redirect()->route('auth.form')->withErrors(['message' => 'Сначала войдите в систему']);
        }

        return view('profile', ['user' => $user]);
    }

    public function logout(Request $request)
    {
        // Удаляем данные из сессии
        $request->session()->forget('user');

        return redirect('/');
    }
}

3. Настройка роутов. Обновим routes/web.php, чтобы все роуты ссылались на методы контроллера:
web.php:
<?php

use App\Http\Controllers\AuthController;
use Illuminate\Support\Facades\Route;

// Главная страница
Route::get('/', function () {
    return view('welcome');
});

// Авторизация
Route::get('/auth', [AuthController::class, 'showLoginForm'])->name('auth.form');
Route::post('/auth', [AuthController::class, 'login'])->name('auth.login');

// Личный кабинет
Route::get('/profile', [AuthController::class, 'profile'])->name('profile');

// Выход
Route::get('/logout', [AuthController::class, 'logout'])->name('auth.logout');



Обновление шаблонов​

Чтобы пользователи видели сообщения об ошибках, добавим их в шаблон авторизации resources/views/auth.blade.php:
auth.blade.php:
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Авторизация</title>
</head>
<body>
    @if ($errors->any())
        <div style="color: red;">
            @foreach ($errors->all() as $error)
                <p>{{ $error }}</p>
            @endforeach
        </div>
    @endif

    <h1>Вход в личный кабинет</h1>
    <form action="/auth" method="POST">
        @csrf
        <label for="nickname">Ник:</label>
        <input type="text" id="nickname" name="nickname" required>
        <br>
        <label for="password">Пароль:</label>
        <input type="password" id="password" name="password" required>
        <br>
        <button type="submit">Войти</button>
    </form>
</body>
</html>

Отображение данных пользователя в личном кабинете. В файле resources/views/profile.blade.php выведем данные из базы:
profile.blade.php:
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Личный кабинет</title>
</head>
<body>
    <h1>Добро пожаловать, {{ $user->nickname }}!</h1>
    <p>Ваш email: {{ $user->email }}</p>
    <p>Игровой баланс: {{ $user->player_money }}</p>
    <p>ID скина: {{ $user->player_skin }}</p>
    <p>Донат счет: {{ $user->player_donate }}</p>
    <a href="/">Вернуться на главную</a>
</body>
</html>

samp.png
В Blade мы можем создать основной (родительский) шаблон resources/views/layouts/app.blade.php
app.blade.php:
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Мой сайт</title>
</head>
<body>
    <header>header</header>

    <div id="content">
        @yield('content')
    </div>

    <footer>footer</footer>
</body>
</html>

Создание дочернего шаблона resources/views/home.blade.php:
home.blade.php:
@extends('layouts.app')

@section('content')
    <h1>Добро пожаловать на ваш сайт!</h1>
    <a href="/auth">Войти</a>
@endsection

В принципе, это базовая и максимально простая настройка авторизации. Вам остается только добавить собственную вёрстку. Также рекомендую использовать Middleware для защиты роутов, например, роута личного кабинета. Тему миграций в данном примере я не затронул, но советую изучить её самостоятельно, так как это важный аспект работы с базой данных. Надеюсь, у вас всё получилось! Желаю успешной и продуктивной разработки ваших проектов!



Готовый сайт для SAMP проекта: https://www.blast.hk/threads/225825/


Я намеренно выбрал подход с базовыми примерами, чтобы максимально упростить вход в Laravel для новичков, которые до сих пор работают с чистым PHP. Когда человек впервые сталкивается с Laravel, ему может быть сложно сразу разобраться в таких концепциях, как MVC, Dependency Injection или Service Container. Поэтому моя цель - дать базу, которая покажет простоту и мощь Laravel, без избыточных сложностей на старте.

Паттерны и принципы, безусловно, важны, но новичку важно сначала увидеть результат. Когда он увидит, как легко можно реализовать авторизацию с Laravel, он захочет углубиться в изучение фреймворка, а уже затем освоит лучшие практики. Я также считаю, что аналогии с ванильным PHP - хороший инструмент, но их нужно вводить постепенно, чтобы не перегрузить материал.

На данном этапе статья с базовыми примерами рассчитана на тех, кто только делает первые шаги, и для них слишком сложные темы могут быть пугающими. Главная цель - мотивировать их изучать Laravel дальше.


Если тема будет интересна и актуальна, я готов написать полноценную статью о том, как более грамотно реализовать авторизацию.
 
Последнее редактирование:
  • Нравится
  • Bug
Реакции: cute_filatov и XRLM

Revalto

Известный
532
225
Откройте файл routes/web.php, который отвечает за определение роутов вашего сайта. Добавим туда наши роуты:
У Laravel есть Route::view();
- что сокращает эти Route::get с return view();
Отображение формы авторизации:
Имеет ли смысл создавать метод с return view(), когда есть Route::view() ?

$hashedPassword = md5($password);
Имеет ли смысл использовать md5 для пароля, когда у Laravel уже есть AES-256-CBC шифрование?
'nickname' => 'required|string',
Возможно стоит добавить валидацию на проверку того, существует ли уже nickname в базе данных (exists)
$request->session()->put('user', $user);
Хм, есть готовая реализация от Laravel:
Auth::login($user); и $request->setUserResolver(fn () => $user);

$user = $request->session()->get('user');
Тогда можно будет использовать Auth::user() / $request->user()
 

Andrey Markelov

Новичок
Автор темы
7
7
У Laravel есть Route::view();
- что сокращает эти Route::get с return view();
> Эта статья для тех, кто вообще не знаком с Laravel. Рассказывать начинать нужно с базы.

Имеет ли смысл создавать метод с return view(), когда есть Route::view() ?
> Имеет, мы показывай базовый функционал и примерно как это работает. Статья для совсем-совсем начинающих.

Имеет ли смысл использовать md5 для пароля, когда у Laravel уже есть AES-256-CBC шифрование?
> Я писал для пользователей в сфере SAMP, в PAWN пароли хранятся в MD5 формате.

Возможно стоит добавить валидацию на проверку того, существует ли уже nickname в базе данных (exists)
> Нет для этой статьи. Здесь показываю как вкатиться с минимальными настройками для авторизации. Для более продвинутого уровня, можешь создать отдельную тему.

Хм, есть готовая реализация от Laravel:
Auth::login($user); и $request->setUserResolver(fn () => $user);
> Здесь кастомная регистрация из-за MD5 формата для пароля


Это здорово, если у тебя есть понимания в Laravel, но когда мы пытаемся что-то объснить, начинаем с самого простого, показываем на простых примерах, особенно для пользователей, которые до сих пор делают себе сайты на голом PHP. Поэтому затрагивать какие-то темы - в данной статье не имеет смысла.


По поводу пароля в MD5 формате уже писал:
https://www.blast.hk/threads/225825/

Пароль​

Насколько мне известно, большинство SAMP-проектов используют формат MD5 для хранения паролей. Однако Laravel и его пакеты для работы с авторизацией не поддерживают MD5 из-за его уязвимости. Поэтому было принято решение написать собственную реализацию авторизации. Функционал авторизации и смены пароля полностью работает с MD5. При этом авторизация в административную панель не использует MD5 и реализована с использованием более безопасных методов. Если в вашем проекте пароли хранятся не в формате MD5, вам потребуется немного изменить логику работы с паролями, чтобы адаптировать проект. Также настоятельно рекомендую добавить двухфакторную аутентификацию, если вы используете MD5 для хранения паролей, чтобы повысить уровень безопасности.
 

Andrey Markelov

Новичок
Автор темы
7
7
Кто тебе сказал этот бред? В 0.3.7 встроен 256, md5 не используется с года так 15(это дополнительный плагин был и есть), сейчас же, часто, bcrypt
Понял, за pawn давно не слежу, чекнул пару модов, спросил у ребят, говорили что в md5 хранят.

upd: Добавил код для bcrypt
 
Последнее редактирование:

MrCreepTon

Неизвестный
Всефорумный модератор
2,205
4,992
Возможно стоит добавить валидацию на проверку того, существует ли уже nickname в базе данных (exists)
Можно переложить эту задачу на БД
Это здорово, если у тебя есть понимания в Laravel, но когда мы пытаемся что-то объснить, начинаем с самого простого, показываем на простых примерах, особенно для пользователей, которые до сих пор делают себе сайты на голом PHP. Поэтому затрагивать какие-то темы - в данной статье не имеет смысла.
Имеет. Почему сразу не показывать паттерны ларавела и не проводить аналогию с ванильным php?
 

Andrey Markelov

Новичок
Автор темы
7
7
Можно переложить эту задачу на БД

Имеет. Почему сразу не показывать паттерны ларавела и не проводить аналогию с ванильным php?

Я намеренно выбрал подход с базовыми примерами, чтобы максимально упростить вход в Laravel для новичков, которые до сих пор работают с чистым PHP. Когда человек впервые сталкивается с Laravel, ему может быть сложно сразу разобраться в таких концепциях, как MVC, Dependency Injection или Service Container. Поэтому моя цель - дать базу, которая покажет простоту и мощь Laravel, без избыточных сложностей на старте.

Паттерны и принципы, безусловно, важны, но новичку важно сначала увидеть результат. Когда он увидит, как легко можно реализовать авторизацию с Laravel, он захочет углубиться в изучение фреймворка, а уже затем освоит лучшие практики. Я также считаю, что аналогии с ванильным PHP - хороший инструмент, но их нужно вводить постепенно, чтобы не перегрузить материал.

На данном этапе статья с базовыми примерами рассчитана на тех, кто только делает первые шаги, и для них слишком сложные темы могут быть пугающими. Главная цель - мотивировать их изучать Laravel дальше.


Если тема будет интересна и актуальна, я готов написать полноценную статью о том, как более грамотно реализовать авторизацию.