Как реализовать функцию auth через колбек в JavaScript
Что проверяют
Знаете ли вы соглашения асинхронного JavaScript: колбек с ошибкой первым аргументом, гарантию единственного вызова, одинаково асинхронное поведение во всех ветках. Часто задача продолжается: оберните auth в промис и перепишите вызов через async/await.
Как отвечать
Покажите контракт функции и соблюдайте его:
- сигнатура:
auth(login, password, callback), гдеcallback(err, user). Ошибка всегда объектError(лучше свой класс с полемcode), а не строка, иначе у вызывающего нет стека и типа; - ровно один вызов: колбек вызывается один раз, либо с ошибкой, либо с результатом. Никогда оба и никогда дважды;
- всегда асинхронно: даже если ошибка валидации известна сразу, вызывайте колбек через
queueMicrotaskилиsetTimeout. Функция, которая иногда отвечает синхронно, а иногда нет, ломает порядок кода у вызывающего; - внутри:
fetchна эндпоинт логина методомPOSTсcredentials: 'include', проверкаresponse.ok, таймаут черезAbortSignal.timeout().
Обёртка в промис:
const authAsync = (login, password) =>
new Promise((resolve, reject) =>
auth(login, password, (err, user) => (err ? reject(err) : resolve(user))));В Node.js то же даёт util.promisify(auth), если колбек идёт последним аргументом и следует соглашению. Скажите, почему колбеки сегодня в основном в легаси: вложенность, ручная обработка ошибок на каждом уровне и невозможность try/catch вокруг асинхронного вызова.
Где спотыкаются
Пишут fetch(url).then(data => cb(null, data)).catch(err => cb(err)). Если исключение бросит сам колбек, catch поймает его и вызовет колбек второй раз. Правильно передать два обработчика в then(onOk, onErr) или вызвать колбек вне цепочки.
Проверяют логин и пароль прямо на клиенте, сравнивая со строками в коде. Любой пароль из бандла читается в DevTools, проверка возможна только на сервере.
Кладут полученный токен в localStorage. Он доступен любому скрипту на странице, и одна XSS уводит сессию. Надёжнее httpOnly-кука, которую выставляет сервер.