Налаштування бандлу

Версія 16.1 додана 2024/05/09 18:24 автором Ashterix

Всі налаштування бандла знаходяться в файлі config/packages/ufo_json_rpc.yaml.

Є можливість налаштувати параметри захисту API та деякі параметри формату даних, що віддається при запиті документації.

security

Наразі єдиним механізмом захисту доступу до вашого API є встановлення перевірки ключа доступу (api_token).

protected_methods

Цей параметр приймає масив назв http методів, які мають бути захищені.

За замовченням ввімкнут захист лише для методу POST. Ви можете:

  • вказати пустий масив [] щоб зробити API повністю відкритим
config/packages/ufo_json_rpc.yaml
1
2
3
ufo_json_rpc:
   security:
       protected_methods: []
  • вказати додатково захист для методу GET, що зробить запит документації недоступним без токену в заголовках запиту
config/packages/ufo_json_rpc.yaml
1
2
3
ufo_json_rpc:
   security:
       protected_methods: ['GET', 'POST']

Якщо ви захищаєте ваш API через protected_methods, вам необхідно налаштувати токени, по яким буде відкритий доступ.

Перш за все, треба визначитися з назвою токену.

token_key_in_header

Компонент RpcSecurity буде шукати в заголовках запиту специфічний ключ, який ви можете встановити в налаштуваннях пакету, значення за замовченням token_key_in_header: 'Ufo-RPC-Token', ви можете встановити будь-яке інше значення яке відповідає наступним вимогам.


Вимоги до формування заголовків протоколу HTTP

clients_tokens

Тепер слід вказати масив клієнтськіх токенів, які будуть мати доступ до API.

Тут є певна варіативність.

Токени в параметрах

НЕ РЕКОМЕНДОВАНО!!!

Цей підхід допускається лише для локального тестування API

Є можливість прописати токени хардкодом прямо в файлі налаштувань.

Це погано з позиції безпеки, якщо код зберігається в публічному репозиторію, то до цього токену буде мати доступ кожен.

config/packages/ufo_json_rpc.yaml
1
2
3
4
5
6
7
ufo_json_rpc:
   security:
       protected_methods: ['GET', 'POST']
       token_key_in_header: 'Ufo-RPC-Token'
       clients_tokens:
            - 'ClientTokenExample'  # hardcoded token example. Importantly!!! Replace or delete it!
            

Токени в змінних оточення

Це найбільш доцільний механізм у разі, якщо ви розробляєте сервіс для розподіленого бекенду, що написаний на SOA (Сервіс-Орієнтована Архітектура). Зазвичай, в такому випадку, вам треба відкрити доступ до апі одному або обмеженій кількості клієнтських додатків і оновлення ключів не буде відбуватися занадто часто.

В такому випадку можна прописати токени в змінних оточення (файл .env.local під час локальної розробки). Цей механізм достатньо безпечний з боку збереження доступів.

.env.local
1
2
TOKEN_FOR_APP_1=9363074966579432364f8b73b3318f71
TOKEN_FOR_APP_2=456fg87g8h98jmnb8675r4445n8up365
config/packages/ufo_json_rpc.yaml
1
2
3
4
5
6
7
ufo_json_rpc:
   security:
       protected_methods: ['GET', 'POST']
       token_key_in_header: 'Ufo-RPC-Token'
       clients_tokens:
            - '%env(resolve:TOKEN_FOR_APP_1)%'   # token example from .env.local
            - '%env(resolve:TOKEN_FOR_APP_2)%'   # token example from .env.local

Токени для користувача

Припускаю, що у вас може виникнути потреба зробити персональні ключі для користувачів вашого додатку, можливо ви захочете впровадити ліміти або інші обмеження.
В такому випадку вам не потрібно вказувати перелік токенів в конфігах, ви можете зберігати їх в базі даних або іншому місці згідно вашій бізнес-логіки. Єдина вимога, у вас має бути сервіс, який вміє перевіряти чи існує наданий токен. 

Для того, щоб JsonRpcServer міг використовувати вашу логіку, доведеться реалізувати власний клас, що реалізує інтерфейс Ufo\JsonRpcBundle\Security\Interfaces\ITokenValidator

Приклад власного валідатора токенів

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

namespace App\Services\RpcSecurity;

use App\Services\UserService;
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
use Ufo\JsonRpcBundle\Security\Interfaces\ITokenValidator;
use Ufo\RpcError\RpcInvalidTokenException;

class UserTokenValidator implements ITokenValidator
{

   public function __construct(protected UserService $userService) {}

   public function isValid(string $token): bool
   {
       try {
           $this->userService->getUserByToken($token);
           return true;
        } catch (UserNotFoundException $e) {
           throw new RpcInvalidTokenException(previous: $e);
        }
    }
}

ВАЖЛИВО!!!
Метод isValid має повертати true якщо токен існує і валідний, або викидати Ufo\RpcError\RpcInvalidTokenException в іншому разі.

Після цього вам потрібно в файлі config/services.yaml прописати що класи, що мають залежність від інтерфейса ITokenValidator мають приймати ваш новий клас.

config/services.yaml
1
2
3
4
5
6
7
8
9
10
parameters:
  # some parameters list
  # ...

services:
  # some services list
  # ...

   Ufo\JsonRpcBundle\Security\Interfaces\ITokenValidator:
       class: App\Services\RpcSecurity\UserTokenValidator