Работа на Vesp /

Авторизация в системе

Как мы уже выяснили в прошлой заметке, пользователь авторизовывается в контроллерах при каждем запросе с помощью токена JWT, который передаётся или в заголовках, или в GET параметре, или получается из куки.

Теперь давайте посмотрим, как происходит получение этого токена пользователем.

Согласно нашему route.php запросы на авторизацию принимаются по адресу api/security/login контроллером App\Controllers\Security\Login, который расширяет Vesp\Controllers\Security\Login:

<?php
// Это оригинальный контроллер из vesp/core
namespace Vesp\Controllers\Security;

use Psr\Http\Message\ResponseInterface;
use Vesp\Controllers\Controller;
use Vesp\Helpers\Jwt;
use Vesp\Models\User;

class Login extends Controller
{
    // Контроллер работает с моделью User
    protected $model = User::class;

    // Обращаться можно только методом POST
    public function post(): ResponseInterface
    {
        // для авторизации требуются username и password
        $username = trim($this->getProperty('username', ''));
        $password = trim($this->getProperty('password', ''));

        // Выбираем пользователя по username
        $user = (new $this->model())->newQuery()->where('username', $username)->first();
        // Если есть такой, и указан верный пароль
        if ($user && $user->verifyPassword($password)) {
            // Проверяем его статус, и возвращаем токен, или ошибку
            return !$user->active
                ? $this->failure('This user is not active', 403)
                : $this->success(['token' => Jwt::makeToken($user->id)]);
        }

        // Авторизовать не удалось - возвращаем ошибку
        return $this->failure('Wrong username or password');
    }
}
Читать далее
Работа на Vesp /

Проверка прав доступа в контроллерах

Мы продолжаем знакомиться с внутренним устройством Vesp и сегодня пришла пора поговорить о системе прав доступа к данным.

После работы с MODX мне не хотелось изобретать что-то сложное, поэтому я придумал следующее:

  1. Права доступа прописываются группе, а не пользователю и хранятся в JSON колонке scope (область действия)
  2. Каждый пользователь может принадлежать только к одной группе
  3. Права в группе могут быть указаны для конкретного метода. Если users позволяет любые запросы, то users/get только получение данных, без put, patch и delete.

Таким образом каждой группе можно гибко давать разрешения на конкретные методы в контроллерах.

Когда подобной системы недостаточно, и нужно проверять, например, id автора комментария при редактировании, то мы просто расширяем метод checkScope у контроллера.

Давайте посмотрим, как он работает по-умолчанию.

Читать далее
Работа на Vesp /

Контроллеры Vesp

На прошлых уроках мы работали с миграциями Phinx и моделями Eloquent - это всё сторонние библиотеки, а где же сам Vesp?

А он в контроллерах, которые были написаны под сильным впечатлением от процессоров MODX, и работают через Slim 4. Интересный факт - MODX 3 в своё время планировали завязать именно на Slim, но что-то пошло не так, и эти планы забросили.

Итак, все запросы от пользователей приходят в один-единственный коннектор www/api.php. Он подключает всё нужное файлом core/bootstrap.php (который можно использовать во всяких консольных скриптах) и создаёт экземпляр приложения Slim.

Дальше в это приложение грузятся наши маршруты из файла core/routes.php, и теперь система знает, какой контроллер отвечает за конкретный запрос. Давайте разберёмся с маршрутами.

Читать далее
Работа на Vesp /

Модели Eloquent

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

Модели - это PHP классы, лежащие в core/src/Models, расширяющие Illuminate\Database\Eloquent\Model и представляющие собой записи в соответствующей таблице базы данных. В отличие от MODX и его xDPO, здесь не нужно писать никаких схем и генерировать непонятные map файлы. Одна модель - это всегда один класс и одна таблица в БД, всё очень просто и понятно. Если миграции меняют таблицу, то эти изменения нужно будет отразить и в модели.

Vesp устанавливает 4 модели по умолчанию: File, UserRole, User, UserToken - они отражают записи в таблицах files, user_roles, users и user_tokens соответственно.

Как видно, имена моделей чётко соотносятся с таблицами согласно правилам английского языка - и это не случайно. В Eloquent приняты определённые соглашения по многим ключевым моментам, включая имена моделей и таблиц.

Читать далее
Работа на Vesp /

Разбираемся с миграциями

На прошлом уроке мы дошли до запуска проекта со стандартными таблицами и данными, теперь давайте разберёмся, откуда они взялись.

В директории core/db есть 2 поддиректории: migrations и seeds. В первой, понятно, миграции, а во второй скрипты для "засеивания" начальных данных. Для работы используется Phinx, конфигурация которого хранится в core/phinx.php - там нам ничего менять не нужно, все настройки берутся из настроек окружения .env.

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

Для запуска миграций в Vesp мы используем команду composer db:migrate, для отката composer db:rollback.

Теперь давайте посмотрим на сами файлы миграций.

Читать далее
Работа на Vesp /

Создание нового проекта

Первым делом нам нужно разобраться с вашей рабочей средой. Я использую одни из самых популярных инструментов:

  • Операционную систему MacOS с менеджером пакетов Homebrew
  • Laravel Valet для локальной разработки
  • Интегрированную среду PhpStorm
  • Веб-сервер Nginx
  • База данных MySQL 8.0
  • Php 7.4 и NodeJS 17

Здесь нет ничего особенного, обычный набор веб-разработчика.

Если вы используете такой же сетап, то поздравляю, вам будет максимально легко следовать моим инструкциям - нужно только установить специальный драйвер для Valet из репозитория vesp-valet-driver, что делается простым копированием файла VespValetDriver.php в ~/.config/valet/Drivers.

Структурно Vesp состоит из 2х больших частей: фронтенда на VueJS и бэкенда на PHP. Обе части разрабатываются (и могут быть использованы) независимо друг от друга и хранятся в разных репозиториях:

Объединяются они в 1 общем пакете, который называется просто Vesp и ставится из Packagist при помощи composer. Давайте создадим наш новый проект VespShop.

composer create-project vesp/vesp ./VespShop

Команда create-project у composer не просто скачивает пакеты, но и запускает скрипты, прописанные в composer.json. В нашем случае они устанавливают зависимости Node.js.

Далее заходим в директорию VespShop и делаем valet link vesp-shop, что создаёт в нашем Valet новый сайт vesp-shop.test.

В нём пока ничего нет, поэтому делаем в той же директории composer node:generate и переходим по локальному адресу http://vesp-shop.test - теперь вы должны увидеть такую картинку:

Давайте разберёмся как это всё работает.

Читать далее
Работа на Vesp /

Начинаем новый курс!

Примерно с 2020 года я работаю на своём собственном фреймворке Vesp, который мне очень нравится. Он простой, быстрый, построен на известных популярных решениях и не ограничивает разработчика.

Именно на Vesp построен и сам сайт bezumkin.ru.

Основное отличие заключается в полном разделении бэкенда и фронтенда, что превращает мой сайты уже в веб-приложения, когда отдельно работает API, а интерфейс отправляет в него запросы.

Такое устройство делает работу сервиса очень понятной и прозрачной, и заодно позволяет подключать к API мобильные приложения, или другие сайты для получения данных. Можно делать запросы в API и вовсе без интерфейса, что я в дальнейшем и продемонстрирую.

А еще такие сайты очень удобно разрабатывать и отлаживать, весь код хранится в файлах, можно использовать Xdebug и всякие другие полезности. Прибавьте сюда огромную массу готовых для интеграции библиотек на NpmJs и Packagist.

В общем, после работы с MODX, это просто совершенно другой, гораздо более современный и удобный мир разработки.

Одна проблема - я никак не могу написать к нему документацию, чтобы и другие разработчики могли его оценить по достоинству. Мне кажется, любому программисту гораздо проще писать код, чем рассказывать, как именно он работает.

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

Мы напишем интернет-магазин с минимальным функционалом по типу как у miniShop2, попутно пройдя все этапы создания проекта:

  • Проектирование и создание таблиц для хранения данных
  • Создание моделей для работы с таблицами на Eloquent
  • Напишем контроллеры для работы с этими моделями
  • Работать будем из собственной админки на VueJS
  • И вишенкой на торте сделаем небольшой SPA интернет-магазин на VueJS

Вы освоите: Slim4, Eloquent, VueJS, NuxtJs, Phinx и что там еще по пути потребуется.

Читать далее
Проекты /

zikla.ru: фреймворк против CMS

Тема этой заметки может показаться довольно спорной, но меня давно посещают мысли о принципиальной разнице между разработкой сайтов на CMS и фреймворках.

Мне это видится так. В случае с CMS ты покупаешь костюм в магазине, а потом сам худеешь или толстеешь под него в нужных местах. В случае фреймфорка, тебе шьют костюм на заказ, и он сразу отлично сидит.

Конечно, много зависит от мастера - кто-то и на CMS отлично всё сделает, а кто-то и на фреймворке наваляет ерунды. Но принципиальная разница остатаётся: либо готовая система докручивается под требования заказчика, либо требования заказчика руководят процессом изначально.

Проилюстрирую свои мысли на недавнем примере. Все совпадения неслучайны, персонажи не выдуманы.


Пару месяцев назад ко мне обратился старый друг, назовём его Костя, с просьбой перенести его сайт, сделанный на Битриксе, на мою систему Vesp. На первый взгляд сайт был не очень сложным - просто календарь бронирования циклорамы, а заодно и аренда оборудования из их каталога: фотокамер, объективов, штативов, света и т.д. Можно прийти в студию без ничего, только с моделью, и всё отфотать.

С виду - типичный одностраничный лендинг, но потом там нашлась и оплата заказов, и промокоды, а самое главное - замороченный календарь бронирования, в котором можно выбирать любые интервалы времени для разных дней. То есть, в одном заказе могут быть оформлены съёмки по полчаса, но в течение, например, 3х разных дней.

Сайт уже был сделан большой местной веб-студией, и вместе с лицензией на Битрикс обошёлся в довольно приличные деньги. Но Костя не был доволен ни качеством его работы, ни скоростью с которой веб-студия вносила исправления с улучшениями.

Так как я давно работаю в Pixmill полный день, и сторонние заказы не беру, он ко мне не обращался до последнего, но тут уже всё - пациенту срочно требовалась операция. Да и работа выглядела ерундовой, на пару недель в свободное время по вечерам, не больше.

Что может быть сложного в том, чтобы взять уже готовый проект с вёрсткой, скриптами, данными и перенести на другую систему? В итоге, как вы уже догадались, сайт пришлось делать с чистого листа.

Читать далее
Проекты /

Запущен holztour.ch

Всем привет, сегодня небольшой отчёт о только что запущенном проекте holztour.ch.

Это небольшой швейцарский сервис для туристов, чтобы они знали, какие места можно посетить. Туристы смотрят где вкусно кормят, где можно полазить по горам, поспать и всё такое. А владельцы этих заведений выставляют про них информацию по подписке. Этакий туристический 2GIS.

Проект разработан на Vesp, собственно для работы с ним меня и позвали в Pixmill изначально, в конце 2020. Но, в связи с пандемией, интерес к туризму сильно просел, и проект забуксовал.

Тем не менее, 1 апреля 2022 мы его запустили, хоть и не в окончательном варианте. Планируется еще много доработок по функционалу.

Читать далее
Новости сайта /

Аватарки на сайте

Продолжаю приводить новую версию в порядок, и теперь дело дошло до работы с аватарками.

Исторически я всегда использовал сервис Gravatar. который позволяет вывести фотку пользователя по md5 хэшу от его email. Идея отличная: ты грузишь аватарку один раз и все сайты, на которых ты зарегистрирован, могут её получить.

Но, во-первых, не все пользователи про это знают. И во-вторых, это всё-таки сторонний сервис, который может перестать работать и я останусь без аватарок.

Поэтому на моих сайтах всегда была возможность загрузить аватарку самостоятельно, и теперь я решил реализовать её как давно хотел (нажмите на картинку для запуска GIFки).

По катом немного подробностей.

Читать далее
Новости сайта /

Работа с картинками

С незапамятных времён на bezumkin.ru нельзя было загружать картинки, даже когда такая возможность появилась в дополнении MODX Tickets, на котором сайт был построен.

Но теперь, в связи с полным перезапуском проекта, я обновил и работу с картинками. Вы можете загружать их кнопочкой в редакторе или сразу бросать пачкой в текст.

Выглядит это вот так (нажмите на картинку для запуска GIFки):

А дальше я расскажу, как это работает.

Читать далее
Личный блог /

Валютные платежи после 24.02

Думаю, многим интересно, что стало с платежами из-за рубежа после известных событий. Ведь я совсем недавно написал, как это легко и просто - работать с иностранными заказчиками!

Для ленивых: всё работает, но дольше. Для всех остальных рассказываю подробнее.

За работу мне платят в конце текущего месяца. Февраль был коротким, так что я выставил очередной счёт своим партнёрам 23 февраля, и 25 (в пятницу) они его оплатили. Их швейцарский банк платёж остановил и запросил дополнительные документы для проверки. Документы предоставили, и 28 числа (в понедельник) платёж поехал в РФ.

Читать далее
bezumkin
Василий Наумкин
01.03.2024 04:30
С PWA пока не разбирался, мне кажется это не особо популярная штука. Если надо просто иконки добавит...
bezumkin
Василий Наумкин
22.02.2024 09:23
На здоровье! Держи лайк =)
inetlover
Александр Наумов
27.01.2024 00:06
Василий, спасибо! Извини, тупанул.
bezumkin
Василий Наумкин
22.01.2024 04:43
Давай-давай!
bezumkin
Василий Наумкин
24.12.2023 11:26
Спасибо!
bezumkin
Василий Наумкин
27.11.2023 02:43
Ура!
bezumkin
Василий Наумкин
25.11.2023 08:30
Vesp тянет 2 зависимости: vesp-frontent для фронта и vesp-core для бэкенда. Их можно обновлять, но э...
bezumkin
Василий Наумкин
22.11.2023 08:09
Отлично, поздравляю!
bezumkin
Василий Наумкин
04.11.2023 10:31
На здоровье!
bezumkin
Василий Наумкин
30.10.2023 01:21
Спасибо!