Салют, хабровчане. Следующая статья была написана одним из наших постоянных читателей и определенно не претендует на звание хардкорного материала, но при этом вполне может послужить туториалом для новичка. Ждем в комментариях ваше мнение по статье, а за более хардкорными знаниями приглашаем на наш курс «Framework Laravel».
Всем привет! Сегодня, в столь «удаленное» для всех время работы, я бы хотел разобрать создание несложной todo, в которой можно создавать свои задачи. Звучит как то, что написано в официальной документации Laravel, и так оно и есть — я использую их todo в качестве базовой основы, немного его трансформирую, а основная часть моего рассказа будет про то, как же создавать роль администратора, исоздать очередной нелепый клон Trello.
Как я уже сказал, за основу мы возьмем следующий гайд. Он очень простой и больше концентрируется на работе с миграциями и с роутингом, чем на программировании контроллеров и моделей. К большому сожалению, его не обновляли с версии 5.1 и, если вы только начинаете программировать в Laravel на последней 7 версии (только 3 марта вышла, свеженькая)), роутинг вам придется писать не в
Так же я поменял фреймворк для верстки с bootstrap на bulma. Во-первых, мне он больше нравится, а вот вторых у меня уже была кодовая база blade шаблонов регистраций (хотя, с другой стороны, нарастить страницы регистраций и авторизаций очень просто, я покажу дальше, как).
Эту версию проекта можно скачать здесь в ветке мастер (а в ветке new вы можете скачать готовое приложение). Активировать вы её сможете с помощью следующих команд, при условии, что у вас уже установлен composer и laravel:
Авторизации «из коробки» поменялись с 6 версии. Теперь для быстрого создания нужно поставить пакет, который может вам быстро сгенерировать контроллеры и blade — шаблоны:
В вашем проекте должно появиться несколько новых файлов:
в папке resourses появится подпапка auth, в которой будут файлы blade шаблонов, посвященные авторизации, паролям. Изначально blade-шаблоны сверстаны в bootstrap, однако я их немного трансформировал в bulma, чтобы соблюсти общность css-фрейворка в проекте. Однако, чтобы удобно было пользоваться веб-сайтом, нам потребуется панель навигации. В resources я создал папку includes, в которой разместил вспомогательные файлы — header и nav. Чтобы не занимать много места, скажу, что в header у меня была только head с подключением bulma, а в
Пора уже и обсудить структуру нашего проекта. Потом читатель сможет трансформировать приложение под свои нужды, но сейчас, допустим, я хочу, чтобы в приложении был один администратор (допустим, проджект-менеджер), который может ставить и удалять задачи, и какая-то команда, которая может эти команды видеть. Конечно, было бы уже совсем неплохо, если бы кто-то мог брать задачи и обозначать, что именно он их выполняет, но об этом как-нибудь потом.
Окей, значит у нас будет две группы юзеров и условимся, что увидеть нашу доску задач смогут только авторизованные юзеры, которым дали доступ, а добавлять задачи — некоторые суперадмины. Давайте приступим.
Для небольшого упрощения я решил разбить приложение на две страницы: одну, на которой у нас будет только задачи без возможности редактирования, и вторую, которая будет доступна только суперадмину. Доступную команде страницу я решил назвать
Эта страница выводит только список задач. Для ее отображения я добавлю новый путь в web.php:
Шаблон, в котором у нас тот же список, но с возможностью редактирования и добавления, называется
И этот шаблон, как и оригинальном туториале, расширяется в
Отлично! С внешним видом мы определились, теперь можно переходить к роутингу и созданию наших
Для начала зайдем в модель Users и добавим новые типы пользователей:
Далее заходим в последнюю миграцию таблицы users (папка database/migrations) и добавляем колонку с нашим новым типом данных:
Дальше проходим в
Окей, дальше нам нужно создать нашу middleware для админа. Проще всего это осуществить с помощью следующей команды:
Надеюсь, у вас все получилось. В папке
Дальше нам нужно зарегистрировать наш middleware в
Трансформируем путь dash в
Осталось создать кастомный контролер для нашего администратора:
Редактируем:
Чтобы у вас все с регистрацией заработало конкретно, нужно не забыть поправить редирект в
Теперь администратор у нас может появится только с помощью нашего помощника в терминале tinker:
На этом все. Если вы хотите попробовать готовое приложение, повторю ссылку Конечно, наше приложение прямо сейчас нельзя использовать в продакшене, потому что ваши задачи сможет увидеть каждый, кто зарегистрировался на ресурсе. Но как вы будете ограничивать доступ?
Возможно, у вас есть корпоративная почта, и тогда вы сможете ограничивать доступ в команду с помощью регулярок в валидизации почты. Или вы сможете добавить проверку на членство в команде точно так же, как админа, проделав схожие манипуляции. По традиции, приведу несколько полезный ссылок, для тех, кто только собирается начать осваивать Laravel:
> Чуть более подробная статья, чем в документации, о миграциях в Laravel
> Неплохая статья на Medium про роли в Laravel
> Что у нас свеженького в Laravel 7
Разворот приложений и непрерывный деплой «без боли» с помощью Forge/Envoyer.
Всем привет! Сегодня, в столь «удаленное» для всех время работы, я бы хотел разобрать создание несложной todo, в которой можно создавать свои задачи. Звучит как то, что написано в официальной документации Laravel, и так оно и есть — я использую их todo в качестве базовой основы, немного его трансформирую, а основная часть моего рассказа будет про то, как же создавать роль администратора, и
Создаем основание
Как я уже сказал, за основу мы возьмем следующий гайд. Он очень простой и больше концентрируется на работе с миграциями и с роутингом, чем на программировании контроллеров и моделей. К большому сожалению, его не обновляли с версии 5.1 и, если вы только начинаете программировать в Laravel на последней 7 версии (только 3 марта вышла, свеженькая)), роутинг вам придется писать не в
app/Http/routes.php
, а в routes/web.php
(это правда уже с 6 версии поменялось), и в общем на этом вся разница заканчивается. В итоге, у вас должно получится что-то такое:Так же я поменял фреймворк для верстки с bootstrap на bulma. Во-первых, мне он больше нравится, а вот вторых у меня уже была кодовая база blade шаблонов регистраций (хотя, с другой стороны, нарастить страницы регистраций и авторизаций очень просто, я покажу дальше, как).
Эту версию проекта можно скачать здесь в ветке мастер (а в ветке new вы можете скачать готовое приложение). Активировать вы её сможете с помощью следующих команд, при условии, что у вас уже установлен composer и laravel:
composer install
// создаете файл .env, копируете в него .env example, настраиваетесь под вашу базу данных
php artisan key:generate //устанавливаете ключ безопасности
php artisan serve //запускаете приложение
Создаем авторизацию и регистрацию
Авторизации «из коробки» поменялись с 6 версии. Теперь для быстрого создания нужно поставить пакет, который может вам быстро сгенерировать контроллеры и blade — шаблоны:
composer install laravel/ui
php artisan ui vue --auth
В вашем проекте должно появиться несколько новых файлов:
в папке resourses появится подпапка auth, в которой будут файлы blade шаблонов, посвященные авторизации, паролям. Изначально blade-шаблоны сверстаны в bootstrap, однако я их немного трансформировал в bulma, чтобы соблюсти общность css-фрейворка в проекте. Однако, чтобы удобно было пользоваться веб-сайтом, нам потребуется панель навигации. В resources я создал папку includes, в которой разместил вспомогательные файлы — header и nav. Чтобы не занимать много места, скажу, что в header у меня была только head с подключением bulma, а в
nav.blade.php
было следующее:<nav class="navbar has-background-black-ter" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item has-text-white is-size-4" href="/">
TODO
</a>
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div class="navbar-menu">
<div class="navbar-start">
@if (Auth::check())
<button type="button" class="button is-primary">
<!-- если пользователь зарегистрирован, тогда ->отобразить его ник -->
{{{ Auth::user()->name}}}
</button>
@else
<!-- в другом случае -->
<a class="navbar-item has-text-danger" href="{{route('register')}}">Регистрация</a>
<a class="navbar-item has-text-danger" href="{{route('login')}}">Войти</a>
@endif
@if (Auth::check())
<!-- если зарегистрирован, тогда нам нужно показать как выйти -->
<!-- это можно сделать через форму -->
<a class="navbar-item has-text-danger" href="{{url('/logout') }}" onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
Выйти </a>
<form id="logout-form" action="{{ url('/logout') }}" method="POST" style="display: none;">
{{ csrf_field() }}
</form>
@endif
</ul>
</div>
<div class="navbar-end">
<!-- navbar items -->
</div>
</div>
</nav>
Начинаем создавать нашу архитектуру
Пора уже и обсудить структуру нашего проекта. Потом читатель сможет трансформировать приложение под свои нужды, но сейчас, допустим, я хочу, чтобы в приложении был один администратор (допустим, проджект-менеджер), который может ставить и удалять задачи, и какая-то команда, которая может эти команды видеть. Конечно, было бы уже совсем неплохо, если бы кто-то мог брать задачи и обозначать, что именно он их выполняет, но об этом как-нибудь потом.
Окей, значит у нас будет две группы юзеров и условимся, что увидеть нашу доску задач смогут только авторизованные юзеры, которым дали доступ, а добавлять задачи — некоторые суперадмины. Давайте приступим.
Для небольшого упрощения я решил разбить приложение на две страницы: одну, на которой у нас будет только задачи без возможности редактирования, и вторую, которая будет доступна только суперадмину. Доступную команде страницу я решил назвать
welcome.blade.php
:@include('includes.header')
<body>
@include('includes.nav')
<div class="columns is-centered">
<div class="column is-half">
<div class="panel">
<div class="panel-heading">
Текущие задачи
</div>
<div class="panel-body">
@foreach ($tasks as $task)
<a class="panel-block">
<button class="button is-rounded">
<span>{{ $task->name }}</span>
</button>
@endforeach
</div>
</div>
</div>
</div>
<body>
</html>
Эта страница выводит только список задач. Для ее отображения я добавлю новый путь в web.php:
Route::get('/', function () {
return view('welcome', [
'tasks' => Task::orderBy('created_at', 'asc')->get(),
]);
});
Шаблон, в котором у нас тот же список, но с возможностью редактирования и добавления, называется
task.blade.php
. Он слишком велик, поэтому я размещу его под спойлером:task.blade.php
@extends('layouts.app')
@section('content')
<div class="columns is-centered">
<div class="column is-half">
<div class="panel">
<div class="panel-heading">
Новое дело
</div>
<div class="panel-block">
@include('common.errors')
<!-- Форма для создания тасков -->
<form action="{{ url('task')}}" method="POST">
{{ csrf_field() }}
<div class="field">
<label for="task-name" class="label is-medium">Дело</label>
<input type=" text" name="name" id="task-name" class="input is-medium"
value="{{ old('task') }}">
</div>
<div class="field">
<button type="submit" class="button is-success">
<span class="icon">
<i class="fa fa-btn fa-plus">
</span></i>
<span>Добавить дело</span>
</button>
</div>
</form>
</div>
</div>
<!-- Current Tasks -->
@if (count($tasks) > 0)
<div class="panel">
<div class="panel-heading">
Текущие задачи
</div>
<div class="panel-body">
{{-- <table class="table table-striped task-table">
<thead>
<th>Дело</th>
<th> </th>
</thead>
<tbody> --}}
@foreach ($tasks as $task)
<a class="panel-block">
<button class="button is-rounded">
<span>{{ $task->name }}</span>
</button>
<form action="{{ url('task/'.$task->id) }}" method="POST">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<button type="submit" class="button is-danger">
<span class="icon is-small"> <i class="fa fa-btn fa-trash"></i></span>
<span> Удалить </span>
</button>
</form>
</a>
@endforeach
</div>
</div>
@endif
</div>
</div>
@endsection
И этот шаблон, как и оригинальном туториале, расширяется в
app/layouts.blade.php
:@include('includes.header')
<body>
@include('includes.nav')
@yield('content')
</body>
</html>
Отлично! С внешним видом мы определились, теперь можно переходить к роутингу и созданию наших
middlewares
.Для начала зайдем в модель Users и добавим новые типы пользователей:
const ADMIN_TYPE = 'admin';
const TEAM_TYPE = 'team';
#и добавляем в самый конец класса функцию проверки:
public function isAdmin(){
return $this->type === self::ADMIN_TYPE;
// требуем доложить тип пользователя
}
Далее заходим в последнюю миграцию таблицы users (папка database/migrations) и добавляем колонку с нашим новым типом данных:
$table->string('type')->default('team');
// пока предполагаем, что кроме команды у нас сервисе больше никого нету
Дальше проходим в
app/Http/Controllers/Auth/RegisterController.php
и немного редактируем функцию create (она тоже в версии 5 выглядела немного по другому):protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'type' => User::TEAM_TYPE,
]);
}
Окей, дальше нам нужно создать нашу middleware для админа. Проще всего это осуществить с помощью следующей команды:
php artisan make:middleware IsAdmin
Надеюсь, у вас все получилось. В папке
HTTP/middleware
у вас должен был появится isAdmin.php
, в которой функцию handle нужно отредактировать следующим образом:public function handle($request, Closure $next)
{
if(auth()->user()->isAdmin()) {
return $next($request);
// если пользовать админа, пропускаем. Если нет - тогда отправляем домой
}
return redirect('/');
}
Дальше нам нужно зарегистрировать наш middleware в
app/HTTP/Kernel
, чтобы им можно было воспользоваться:protected $routeMiddleware = [
#множество других мидлевеиров, не так важных для этой истории
is_admin' => \App\Http\Middleware\IsAdmin::class,
];
Трансформируем путь dash в
web.php
, который должен иметь возможность видеть только суперадмин:Route::get('/dash', function () {
return view('tasks', [
'tasks' => Task::orderBy('created_at', 'asc')->get(),
]);
})
->middleware('is_admin')
->name('admin');
# не забываем добавить авторизацию и возможность разлогироваться
Auth::routes();
Route::post('/logout', 'Auth\LoginController@logout')->name('logout');
Осталось создать кастомный контролер для нашего администратора:
php artisan make:controller AdminController
Редактируем:
public function __construct()
{
$this->middleware('auth');
}
public function admin()
{
return view('admin');
}
Чтобы у вас все с регистрацией заработало конкретно, нужно не забыть поправить редирект в
RouteServiceProvider.php
в app/HTTP/Providers
, потому он изначально рассчитан на шаблон home:public const HOME = '/';
Теперь администратор у нас может появится только с помощью нашего помощника в терминале tinker:
php artisan tinker
use App\User;
User::where('email', 'admin@mail.com')->update(['type' => 'admin']);
//даем нашем пользователю права админа
На этом все. Если вы хотите попробовать готовое приложение, повторю ссылку Конечно, наше приложение прямо сейчас нельзя использовать в продакшене, потому что ваши задачи сможет увидеть каждый, кто зарегистрировался на ресурсе. Но как вы будете ограничивать доступ?
Возможно, у вас есть корпоративная почта, и тогда вы сможете ограничивать доступ в команду с помощью регулярок в валидизации почты. Или вы сможете добавить проверку на членство в команде точно так же, как админа, проделав схожие манипуляции. По традиции, приведу несколько полезный ссылок, для тех, кто только собирается начать осваивать Laravel:
> Чуть более подробная статья, чем в документации, о миграциях в Laravel
> Неплохая статья на Medium про роли в Laravel
> Что у нас свеженького в Laravel 7
Разворот приложений и непрерывный деплой «без боли» с помощью Forge/Envoyer.
Sky4eg
Я до конца ждал когда вы отрефакторите роут!
Вы позиционируете себе как онлайн образование и при этом в роутах вы мало того, что дергаете вьюхи, так еще и тащите данные с базы! Я понимаю такой уровень статей в песочнице от тех кто хочет получить инвайт, но от компании которая пытается учить людей! Увы (
В очередной раз по ларке у вас провал!
MaxRokatansky Автор
Прочитайте пожалуйста заголовок. В нем написано о том, что статья написана нашим читателем и может претендовать максимум на звание туториала для начинающих
Sky4eg
Читал, но публиковать такое я бы не стал. Тут явные ошибки работы с ларкой, кто-то же может посмотреть на это и начать так делать! Это же не личный бложик на котором можно писать что угодно! Эта статья на хабре от автора, который предлагает курсы!
Stasgar
Частично согласен с аргументами Sky4eg
Я ведь верно понимаю, что оригинальный автор проходит ваши курсы? Ну вот было бы здорово перед публикацией, чтобы статью оценил один из ваших преподавателей и дал бы советы неопытному человеку. А так просто публиковать статью без предобработки мне кажется не очень хорошим решением.
Понятно, что статья написана начинающим, но я бы хотя бы подкорректировал её под минимальный стандарт качества, как кода, так и разметки хабра.