Сервис предоставляет два способа удостоверения пользователя

  1. JWT
  2. Basic auth
  3. Сравнение
  4. API Endpoints
  5. Политика безопасности в отношении пароля

JWT

Используются два токена: verify & refresh

Порядок запросов

  1. Логин по ссылке: /api/jwt/token/, пример запроса: клиент - https://httpie.io/
    http post 77.223.101.127:9000/api/jwt/token/ username=root password=Http200
  2. Из полученной пары первый сеттим в заголовок 'HTTP_AUTHORIZATION': 'Bearer <token_verify>' для тех запросов что требуют авторизации, пример:
    http get 77.223.101.127:9000/api/user/list 'AUTHORIZATION:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjIzOTQ2NTc4LCJqdGkiOiIzYWZjYzAzZDQ5YWU0OGYwODNlZWM3MjJiYWJmZjkwNCIsInVzZXJfaWQiOjIsIm5hbWUiOiJyb290IiwiZ3JvdXBzIjpbXX0.FrGn6hSwztUygKkttYYvVvFajCT62FzWU9WPgZTmDgk'
  3. Перед каждым запросом смотрим на дату годности первого токена, если она истекла, то рефрешим всю пару по ссылке: /api/jwt/token/refresh/, пример:
    http post 77.223.101.127:9000/api/jwt/token/refresh/ refresh=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTYyMzMxNDk2NCwianRpIjoiMjA2OTcyNTFjYzg2NDVlMDhjNmExYWMxNGE1MWMzMTEiLCJ1c2VyX2lkIjoyfQ.rYg_yw-prwyHBRI1UcGMqPo6SSH3lW54O_s0dbSrbxI
  4. Иногда нужно просто верифицировать имеющийся токен, /api/jwt/token/verify/, пример:
    http post 77.223.101.127:9000/api/jwt/token/verify/ token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjIzMjk2NjA5LCJqdGkiOiI3ZDUyNWVmNzM2OWM0ZWUwOWExMjcwZTI4N2FhMWRhMCIsInVzZXJfaWQiOjJ9.f-oQJvmWS54t6Ep7K9bJxREu-FrwxfJa-xAZqIjuCjU

Basic auth

Порядок запросов

  1. Логин по ссылке: /api/rest-auth/login/, пример запроса:
    http post 77.223.101.127:9000/api/rest-auth/login/ username=root password=Http200
  2. В ответе получим токен, который сеттим в заголовок 'HTTP_AUTHORIZATION': 'token <token>' для тех запросов что требуют авторизации, например:
    http post 77.223.101.127:9000/api/user/ 'Authorization:token 1f890d847a08df26952cdaa681a98465345a8c45'

Сравнение

  1. + ЖВТ не хранится в БД
  2. + Позволяет реализовать настоящий RESTfull API
  3. + Безопаснее
  4. + Сам по себе носитель инфы
  5. + Быстрее и, чем больше будет юзеров, тем разница будет заметнее.
  6. - Сложнее в использовании

API Endpoints

Тип Адрес Параметры Ответ, пример Описание Разрешения
POST /api/rest-auth/registration/ {'username': 'tst', 'email': 'test@test.loc', 'password1': '123root', 'password2': '123root'} HTTP 201 any
POST /api/dj-rest-auth/password/change/ {'new_password1': 'Http900','new_password2': 'Http900'} HTTP 200 {'detail': 'Новый пароль сохранён.'} owner only
POST /api/password/reset/confirm/ {'email': 'test@list.ru'} HTTP 200 any
POST /api/password/reset/confirm/ {'token':token, 'password':'Http500'} HTTP 200 any
GET /api/group/list/ [{'id': 1, 'name': 'test_name'}] staff only
POST /api/group/create/ {'name': 'test'} HTTP 201 staff only
PATCH /api/group/1/update/ {'name': 'test_name'} HTTP 200 staff only
GET /api/group/users/test/?is_superuser=true&is_staff=true {'name': 'test'} HTTP 200
[{'username': 'root', 'email': 'user@loc.loc', 'groups': [1], 'id': 1}, {'username': 'test2', 'email': 'test2@loc.loc', 'groups': [1, 2], 'id': 2}]
staff only
GET /api/group/ {'testGroup': {'id': 1, 'users': [{'user_id': 1, 'username': 'user', 'phone': 8885552277}, {'user_id': 2, 'username': 'test2'}, {'user_id': 3, 'username': 'test3'}]}, 'testGroup2': {'id': 2, 'users': [{'user_id': 2, 'username': 'test2'}]}}
состав полей может меняться
staff only
GET /api/user/filter/ id, username, first_name, last_name, role, group, is_superuser, is_staff, is_active, page, page_size, any
В поле group указываем имя группы. Поиск по этим значениям производится по вхождению в значение поля, те если есть пользователи тест1 и тест2, а в параметре username указано тест, то вернутся оба.
Поиск с точным совпадением: id, role, is_superuser, is_staff, is_active.
Поиск с совпадением по части: username, group, phone, last_name, first_name.

Поля page, page_size - числа, первое номер запрашиваемой страницы, второе кол-во итемов на ней. Если они не указаны, то будут использованы значения по умолчанию 1 и 25 соответственно. Если запрос отправлен с полем any, то будет произведен поиск с частичным совпадением сразу по трем полям: last_name, phone, email.
Все поля опциональны. Текстовые поля валидируются по длине, разрешается от 3 до 30 символов.
HTTP 200
{'count': 18, 'next': 'http://testserver/api/user/filter/?page=3&page_size=2', 'previous': 'http://testserver/api/user/filter/?page_size=2', 'results': [{'username': 'test3', 'email': 'test3@loc.loc', 'groups': [{'id': 1, 'name': 'testGroup'}], 'id': 3, 'first_name': '', 'last_name': '', 'is_superuser': False, 'is_staff': False, 'is_active': True, 'profile': {'phone': '', 'role': 'client', 'delivery': ''}}, {'username': 'test5', 'email': 'test5@loc.loc', 'groups': [], 'id': 4, 'first_name': '', 'last_name': '', 'is_superuser': False, 'is_staff': False, 'is_active': True, 'profile': {'phone': '', 'role': 'client', 'delivery': ''}}]}
Поле count содержит общее кол-во итемов в выборке. Поле previos содержит ссылку для предыдущей страницы, соотвественно поле next для следующей. Поле results содержит собственно данные.
staff only
GET /api/user/list/ [{'username': 'user', 'id': 1, 'groups': [{'id': 1, 'name': 'testGroup'}], 'phone': 8885552277}, {'username': 'test2', 'id': 2, 'groups': [{'id': 1, 'name': 'testGroup'}, {'id': 2, 'name': 'testGroup2'}]}, {'username': 'test3', 'id': 3, 'groups': [{'id': 1, 'name': 'testGroup'}]}]
состав полей может меняться
authorized only
POST /api/user/list/ filter=[1,2], если filter не указан или пустой, то вернет всех юзеров [{'username': 'user', 'id': 1, 'groups': [{'id': 1, 'name': 'testGroup'}], 'phone': 8885552277}, {'username': 'test2', 'id': 2, 'groups': [{'id': 1, 'name': 'testGroup'}, {'id': 2, 'name': 'testGroup2'}]}, {'username': 'test3', 'id': 3, 'groups': [{'id': 1, 'name': 'testGroup'}]}]
состав полей может меняться
authorized only
GET /api/user/ Все поля за исключением пароля any, authorized only
PATCH /api/user/1/update/ {'username': 'test_rename_user','first_name': 'Остап',# 'last_name': 'Бендер', 'password': 'Http700' # пароль будет просто проигнорирован 'profile': {'phone': 8885552277},}
допустимы все поля за исключением пароля
Все поля за исключением пароля, допустимо частичное обновления, те ни одно поле не обязательно staff only
PATCH /api/user/1/update/ {"is_active": false} HTTP 200. Пример бана юзера, осторожнее можно забанить самого себя и утратить доступ к админке staff only
GET /api/user/1/ Все поля за исключением пароля staff only
PATCH /api/user/1/group-update/ {"groups":[1,2]} HTTP-200 Все поля пользователя за исключением пароля или HTTP-400, если такой группы не существует. staff only
DELETE /api/group/1/ HTTP 204 || 404 если группы не существует staff only
DELETE /api/user/1/delete/ HTTP 204 || 404 если юзера не существует staff only
PATCH /api/user/update/ HTTP 200 authorized only
POST /api/jwt/token/ payload = {
username: process.env.telegram_username,
password: process.env.telegram_password,
days: 0, // дни истечения срок валидности токена
hours: 3, // тоже, но часы
minutes: 0, // тоже, минуты
// полезная нагрузка токена, всё что сюда записано будет в поле payload.load
load: {
company_id: 333,
registry_id: 555
   }
}
техпроцесс
1. запрашиваем токен, из ответа берем только ACCESS токен, refresh отбрасываем, здесь он не нужен.
2. генерим ссылку для бота
3. отправляем, ждем)
4. сверяем данные в токене, тк они подписаны и подменить их не получиться, с данными в параметрах ссылки
5. если всё верно продолжаем обработку запроса
HTTP 200
1. запрос токена:
http post auth.macrobank.pro/api/jwt/token/ username=telegram_bot password='ххххххххх' load={"company_id":"tstID"}
2. верификация:
http post auth.macrobank.pro/api/jwt/token/verify/ token=access_token
authorized only

Политика безопасности в отношении пароля

  1. Пароль не должен быть слишком похож на другие атрибуты.
  2. Минимальная длина - 6 символов
  3. Пароль не может состоять только из цифр.
  4. Слишком простой и часто используемый пароль. Джанго сверяет пароль со своей БД в которой около 20000 простых паролей.