Токен не установлен в куки - PullRequest
3 голосов
/ 29 марта 2020

Таким образом, у нас возникает случайная проблема, когда время от времени токен JWT, который мы храним в куки для аутентификации, не устанавливается в браузере. Теперь 99% времени, когда пользователь заходит на веб-страницу входа в систему, вводит свои данные, он отправляет запрос на сервер, который отправляет обратно свои данные пользователя и токен JWT, установленный в файлах cookie. Время от времени повар ie, похоже, не настроен. Его случайность произошла почти во всех браузерах, но без причины. Это происходит как в нашей локальной, промежуточной и производственной среде. (Я удалил некоторый код по соображениям конфиденциальности)

Внутренняя служба аутентификации создается с использованием Node, а ExpressJS устанавливает токен со следующим кодом:

module.exports.signIn = async function(req, res, next) {
  try {
    const { email, password } = req.body;
    if (!email || !password)
      throwBadRequest("Please enter a valid email and password");

    const data = await Users.get(`?email=${email.toLowerCase().trim()}`);

    const { name, val, options } = await Token.generateCookieParams(data);
    res.cookie(name, val, options);

    return res.json(toDTO(data));
  } catch (err) {
    next(err)
  }
};

Мы используете парсер middleware cook ie, если это поможет. Вот код, который устанавливает токен:

async function generateFor(user, expireTime, special = null) {
    const payload = { id: user._id, type: user.type, account: user.account };
    if (user.entity) {
      payload.entity = user.entity;
    }
    if (special) {
      payload.special = special;
    }
    const token = await jwt.sign(payload, config.secret, {
      expiresIn: expireTime
    });
    return token;
  }

async function generateCookieParams(user) {
    const expireTime = 60 * 60 * 12; // 12 hour
    const token = await Token.generateFor(user, expireTime);
    return { name: config.tokenKey, val: token, options: { httpOnly: true } };
  }

Мы используем промежуточное программное обеспечение для управления ядрами в приложении express, и для учетных данных опции установлено значение true.

Затем в внешний интерфейс, мы используем superagent для выполнения всех запросов из приложения реагировать, мы также использовали Ax ios, но у нас есть те же проблемы. Базовый код для сети выглядит следующим образом:

import superagent from "superagent";

const superagentManager = {};

/**
 * POST
 * @param {string} path => the path for the post request
 * @param {object} data => the object you are posting in json format
 */
superagentManager.post = async (path, data) => {
  return await superagent
    .post(path)
    .withCredentials()
    .type("application/json")
    .send(data);
};

/**
 * GET
 * @param {string} path => the path for the get request
 */
superagentManager.get = async path => {
  return await superagent
    .get(path)
    .withCredentials()
    .type("application/json");
};

/**
 * PATCH
 * @param {string} path => the path for the patch request
 * @param {object} data => the object you are posting in json format
 */
superagentManager.patch = async (path, data) => {
  return await superagent
    .patch(path)
    .withCredentials()
    .type("application/json")
    .send(data);
};

/**
 * DELETE
 * @param {string} path => the path for the delete request
 */
superagentManager.delete = async path => {
  return await superagent
    .delete(path)
    .withCredentials()
    .type("application/json");
};

export default superagentManager;

Если кто-нибудь может мне помочь, это будет очень цениться. Система работает, но время от времени, скажем, 1 из каждых 50 логинов не устанавливает токен в браузере. Таким образом, пользовательский объект возвращается из запроса на вход в систему, но дальнейший запрос, который происходит сразу после этого, выдает ошибку, так как в cook ie нет токена. С ростом пользовательской базы ошибка становится все более заметной.

Ответы [ 2 ]

2 голосов
/ 03 апреля 2020

Это похоже на повара ie вопрос!

Таким образом, в браузере есть два способа сохранения состояний с помощью файлов cookie. Сеанс Данные хранятся на сервере и обычно используют какой-то ключ для получения значений, связанных с пользовательскими состояниями. Cookies хранятся на стороне клиента и также отправляются в запросах для определения состояния пользователя. ExpressJS поддерживает возможность использовать оба из них. Для JWT вы, конечно, хотите использовать подход повара ie!

Давайте начнем с рассмотрения вариантов вашего повара ie:

// return { name: config.tokenKey, val: token, options: { httpOnly: true } };

const cookieOptions = {
    httpOnly: true
}

Пока все выглядит хорошо. Вы придерживаетесь рекомендаций по хранению токенов только в формате http * , но для правильного хранения ключа ie вам может потребоваться добавить еще несколько параметров ie.

Вот ссылка для приготовления ie вариантов в express документах . Проверьте описание для «истекает»:

Срок годности повара ie в GMT. Если не указано или установлено значение 0, создает сеанс готовки ie.

По сути, происходит то, что вы не указываете истечение срока действия, поэтому ваш повар ie устанавливается в качестве сеансового повара ie. Это означает, что повар ie уничтожается каждый раз, когда пользователь закрывает браузер.

Бонус:

  • Если ваш сайт использует HTTPS, обязательно установите для повара ie значение secure: true

  • Вы также можете проверить атрибуты sameSite, если он применяется к вашей команде.

1 голос
/ 29 марта 2020

Я не вижу ничего плохого в вашем коде, но некоторые вещи, на которые стоит обратить внимание, уже ушли в прошлое;

  • гарантирует, что ваш клиент не начнет следующий вызов, когда вход в систему по-прежнему происходит. Также убедитесь в правильной обработке ошибок, чтобы показать клиенту, что вход не выполнен.
  • , если у вас есть прокси (например, nginx, haproxy), убедитесь, что заголовок vary настроен правильно
  • , убедитесь, что нет кэширование происходит на сервере И в браузере путем настройки заголовков no-cache и max-age
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...