{"id":22199447,"url":"https://github.com/ilyamur/mytasks_app","last_synced_at":"2025-03-24T23:44:44.046Z","repository":{"id":206737053,"uuid":"447092858","full_name":"IlyaMur/mytasks_app","owner":"IlyaMur","description":"The RESTful API app with JWT authorization written in plain PHP","archived":false,"fork":false,"pushed_at":"2022-01-31T23:49:59.000Z","size":267,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-30T02:43:12.184Z","etag":null,"topics":["crud","jwt-authentication","plain-php","rest-api"],"latest_commit_sha":null,"homepage":"https://rest-todoapp.herokuapp.com/api/signup","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/IlyaMur.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-01-12T05:48:39.000Z","updated_at":"2024-11-29T19:15:42.000Z","dependencies_parsed_at":"2023-11-12T00:20:18.872Z","dependency_job_id":"9fa3ac5b-6fa4-412f-9b96-7f6cce94d8ac","html_url":"https://github.com/IlyaMur/mytasks_app","commit_stats":null,"previous_names":["ilyamur/mytasks_app"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IlyaMur%2Fmytasks_app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IlyaMur%2Fmytasks_app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IlyaMur%2Fmytasks_app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IlyaMur%2Fmytasks_app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/IlyaMur","download_url":"https://codeload.github.com/IlyaMur/mytasks_app/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245372220,"owners_count":20604489,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["crud","jwt-authentication","plain-php","rest-api"],"created_at":"2024-12-02T15:14:21.027Z","updated_at":"2025-03-24T23:44:44.026Z","avatar_url":"https://github.com/IlyaMur.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MyTasks\n\n![CodeSniffer PSR-12](https://github.com/IlyaMur/my_tasks/workflows/CodeSniffer-PSR-12/badge.svg)\n![PHPUnit-Tests](https://github.com/IlyaMur/my_tasks/workflows/PHPUnit-Tests/badge.svg)\n[![Maintainability](https://api.codeclimate.com/v1/badges/1fe9e35cd954bd20623c/maintainability)](https://codeclimate.com/github/IlyaMur/myTasks/maintainability)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/1fe9e35cd954bd20623c/test_coverage)](https://codeclimate.com/github/IlyaMur/myTasks/test_coverage)\n\n**[🇬🇧 English readme](https://github.com/IlyaMur/mytasks_app/blob/master/README_en.md)**\n\n**Содержание**\n  - [О приложении](#о-приложении)\n  - [Установка](#установка)\n    - [Сборка в Docker](#сборка-в-docker)\n    - [Установка локально](#установка-локально)\n    - [Конфигурация](#конфигурация)\n  - [Авторизация по JWT](#авторизация-по-jwt)\n    - [Регистрация](#регистрация)\n    - [Аутентификация](#аутентификация)\n    - [Обновление токена](#обновление-access-token)\n    - [Выход](#выход)\n  - [Авторизация по ключу](#авторизация-по-стандартному-ключу)\n  - [RESTful API](#restful-api)\n  - [Работа с ошибками](#работа-с-ошибками)\n\n## О Приложении  \n\n**MyTasks** - API-приложение созданное на чистом PHP, с поддержкой двух типов авторизации: JWT и стандартным ключом в заголовке.  \nПриложение представляет собой CRUD с полным доступом к ресурсу `tasks` через REST API.\n\nВо время написания приложения целью стояло избегание любых зависимостей и написания всего API-функционала с нуля, особое внимание уделялось безопасности JWT-авторизации.  \n\nДеплой приложения осуществлен на сервис Heroku.   \nAPI **MyTasks** доступен по адресу - https://rest-todoapp.herokuapp.com/api/signup   \n\nДля демонстрации работы API написан клиент на React - https://github.com/IlyaMur/mytasks_api_client\n\nВ приложении реализованы:\n- Системы аутентификации и авторизации.\n- Возможность переключения режимов авторизации между JWT и стандартным ключом в заголовке.\n- Для JWT реализована система Access и Refresh токенов.\n- RESTful-эндпоинт с полным доступом к CRUD-операциям с ресурсом.\n- Валидация поступающих от клиента данных.\n- Семантика HTTP-ответов.\n\n## Установка  \n\nНеобходимо склонировать репозиторий\n\n    $ git clone https://github.com/IlyaMur/mytasks_app.git  \n    $ cd mytasks_app\n\nИ подготовить файл `.env`\n\n    $ make env-prepare\n\n\nИзменить (опционально, будет работать и с настройками по умолчанию) параметры подключения в файле `.env`\n\n```dotenv\nMYSQL_USER='user'\nMYSQL_HOST='mariadb'\nAPACHE_DEFAULT_PORT='80'\nMYSQL_PASSWORD='testpassword'\n...\n```\n\n### Сборка в Docker\n\nПриложение доступно для сборки в Docker.   \n\nСобрать и запустить приложение\n\n    $ make docker-start  \n\nОстановить и удалить контейнеры\n\n    $ make docker-stop  \n\nТак же доступны:\n\n    $ make docker-bash  # запустить сессию bash в контейнере  \n    $ make docker-test  # запустить тесты в контейнере \n\nПо умолчанию приложение будет доступно: `http://localhost/api/tasks`\n\n### Установка локально\n\n`PHP \u003e= 8.0`\n\nДля установки зависимостей:  \n\n    $ make install   \n\nВ настройках веб-сервера установить root в директории `public/`  \n\nВ выбранную СУБД импортировать SQL из файла `database/mytasks_db.sql`    \n\n### Конфигурация  \n\nНастройки конфигурации доступны в файле [config.php](config/config.php)\n\nНастройки по умолчанию включают в себя:\n- Данные подключения к серверу БД. \n- Настройка секретного ключа для хэширования токенов.\n- Регулировка продолжительности жизни Access Token и Refresh Token.\n- Переключение режима авторизации: JWT или стандартный API-ключ.\n- Установки для вывода/скрытия детализации ошибок.\n- Настройка логирования ошибок.\n- Логирование ошибок.\n- Настройка CORS.\n\nДля переопределения настроек в конфигурационном файле доступны соответствующие константы.\n\n## Авторизация по JWT\n\nВ качестве основного варианта авторизации доступна авторизация по JWT (задана по умолчанию).\n\nСрок жизни токенов (регулируется в [config.php](config/config.php)):  \n**Access Token** - 5 минут.  \n**Refresh Token** - 5 дней.\n\n### Регистрация\n\nДля регистрации необходим `POST-запрос` на эндпоинт https://rest-todoapp.herokuapp.com/api/signup   \nВ теле запроса указать в формате JSON:\n\n```\n{\n  \"username\": \"...\",\n  \"email\": \"...\",\n  \"password\": \"...\"\n}\n```\nПри успехе в ответе будет набор токенов:\n```\n{\n  \"accessToken\": \"...\",\n  \"refreshToken\": \"...\"\n}\n```\nПри неудаче вернется JSON с информацией об ошибках.\n\nДля последующих запросов **Access Token** необходимо вставить в заголовок **Authorization**. \n\n### Обновление Access Token\n\nДля обновления **Access Token** небходим `POST-запрос` на https://rest-todoapp.herokuapp.com/api/refresh  \nВ теле должен быть полученный вместе с ним **Refresh Token**:\n\n```\n{\n  \"refreshToken\": \"полученный ранее refreshToken\"\n}\n```\nПри успехе (токен корректен и его срок не истёк) в ответе будет новая пара токенов.\n\n### Аутентификация\n\nhttps://rest-todoapp.herokuapp.com/api/login обеспечит новым набором JWT.  \nВ тело `POST-запроса` необходимо включить JSON со своими логином и паролем.\n\n### Выход\n\nhttps://rest-todoapp.herokuapp.com/api/logout служит выходом из системы.    \nПри `DELETE-запросе` с включенным в тело **Refresh Token** - будет совершено удаление **Refresh Token** из белого списка, дальнейшее его обновление станет невозможным.\n\n## Авторизация по ключу.\n\nПроцедура регистрации схожа с описанной [выше](#регистрация).  \nВ `POST-запрос` на эндпоинт https://rest-todoapp.herokuapp.com/api/signup нужно включить JSON с желаемыми логином, паролем и почтой.\n\nПри успехе в ответе будет получен токен доступа.\n ```\n {\n   \"accessToken\": \"токен доступа\"\n }\n ```\nДля последующих запросов **Access Token** необходимо вставить в заголовок **X-Api-Key**.\n\n## RESTful API\n\nДля работы с REST-ресурсом создан эндпоинт - https://rest-todoapp.herokuapp.com/api/tasks \n\n`Tasks` - типичный To-Do-list. Ресурс, доступный для всех CRUD-операций.\n\n`GET-запрос` на `/tasks` даст список всех задач конкретного пользователя:\n```\n[\n  {\n    ...\n    \"title\": \"Paint a wall\",\n    \"body\": \"In green paint\",\n    ...\n  },\n  {\n    ...\n    \"title\": \"Go for a walk\",\n    \"body\": \"In the park\",\n    ...\n  }\n]\n```\n\n`POST-запрос` на `/tasks` с включенном в тело JSON с данными задачи cоздаст необходимую задачу:\n```\n{\n  \"title\": \"Feed my cat\",\n  \"body\": \"Fish and milk\",\n}\n```\nЗапросы на экземпляр ресурса:  \n\n`GET` на `/tasks/:id`, в ответе вернет конкретную задачу  \n`PATCH` на `/tasks/:id`, с включенными в тело данными изменит конкретную задачу.  \n`DELETE` на `/tasks/:id`, удалит конкретную задачу.  \n\nВсе данные поступающие на сервер валидируются. Ошибки возвращаются клиенту.\n\n## Работа с ошибками\n\nОшибки преобразуются в исключения. Обработчиками обозначены:\n```\nset_error_handler('Ilyamur\\TasksApp\\Exceptions\\ErrorHandler::handleError');\nset_exception_handler('Ilyamur\\TasksApp\\Exceptions\\ErrorHandler::handleException');\n```\n\nПри константе `SHOW_ERRORS` (настраивается в [config.php](config/config.php)) равной `true`, в случае исключения или ошибки клиенту будет выведена полная детализация ошибки.   \nЕсли `SHOW_ERRORS` присвоено значение `false` будет показано лишь общее сообщение.\nДетализированная информация в данном случае будет логироваться в директории `logs/`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filyamur%2Fmytasks_app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Filyamur%2Fmytasks_app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filyamur%2Fmytasks_app/lists"}