В Auth0 есть два способа получить токен:
- Создать аккаунт для пользователя
- Создать m2m клиент с определенными правами.
Разработчики Auth0 дали возможность хранить дополнительную мета-информацию в аккаунтах и клиентах. Если в аккаунте человека нет ограничения на объем данных - в поле можно записать текст размером до 16 мб - то для m2m у нас в распоряжении только 10 полей по 255 символов каждый. Даже на небольшой массив места не хватит.
В проекте мы активно применяем метаинформацию аккаунтов для формирования токена, такие же правила хотим применить и для m2m клиентов. Хочу напомнить, что формирование токена можно кастомизировать с помощью кода на JS, который будет вызван как коллбек на события в Auth0 Flows. К сожалению, ограничения не дают нам такой возможности. Какие у нас есть варианты:
1. Не хранить в токене m2m никакой допинформации.
На бэке можно было бы получать дополнительную инфу по межсервисному запросу. Такое решение усложнит код: придется часть или дублировать, или выносить в общую библиотеку для микросервисов. К тому же, каждый вебзапрос к сервису породит дополнительный запрос на другой микросервис - в итоге перформанс будет снижен и появится очень жесткая зависимость от сервиса данных. Не самое удачное решение.
2. Сжать данные в полях, чтобы умещались в ограничение в 255 символов.
Тут не придумаешь универсального решения - пришлось бы поддерживать собственные алгоритмы сжатия. Но даже после сжатия велик шанс, что полученная строка уместится в поле.
3. Сделать запрос на бэкенд за допинформацией в коллбеке Auth0
Если нет возможности хранить данные в Auth0, так пусть Auth0 получает данные с нашего бэка. Примерная структура кода в Auth0 flow:
const axios = require('axios');
const getData = async function(clientId) {
const options = {
method: 'get',
url: 'https://api.example.net/some-data/' + clientId,
headers: {
'Content-Type': 'application/json',
'x-api-version': '3'
}
};
const response = await axios.request(options);
// Стоит проверить статус ответа и валидность данных
console.log(response.status);
console.log(response.data);
// Здесь мы берем данные из ответа бэкенда
return response.data.permissions
}
// Код коллбека Auth0, создаваемый автоматически
exports.onExecuteCredentialsExchange = async (event, api) => {
const clientId = event.client.client_id;
const permissions = await getAccessData(clientId);
// Записываем данные в токен
const namespace = 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims';
api.accessToken.setCustomClaim(namespace + "/permissions", permissions);
};
После обсуждения мы решили, что это самый оптимальный вариант:
- Токен m2m выписываем с большим лайфтаймом, поэтому обновлять его часто не нужно.
- Сколько бы ни было завтра доп.данных, лимит на метаинформацию в Auth0 на нас не влияет.
Тут важно учесть, как часто токен будет формироваться и каков его лайфтайм. Для пользователей такая схема даст гораздо больше проблем, ведь так время жизни токена - всего 1 час, да и пользователей гораздо больше, чем m2m клиентов.
В случае, если эта схема значительно повлияет на работу системы и нагрузка на микросервис данных будет высокой, то попробуйте кеширование и/или горизонтальное масштабирование сервиса.