Передача cookie в fetch-запрос на другом сабдомене

Вопрос или проблема

Предположим, у меня есть html-страница на mycooldomain.com. На этой странице я выполняю вход на login.mycooldomain.com, используя axios.

    const smartAxiosLogin = axios.create({
        timeout: 5000, // 5 секунд
        baseURL: 'https://login.mycooldomain.com:4000/api',
        withCredentials: true,
    });
    const smartAxios = axios.create({
        timeout: 5000, // 5 секунд
        baseURL: 'https://smartpmoapi.mycooldomain.com:4100/api',
        withCredentials: true,
    });
        $("#login_form").submit(function(e) {
            e.preventDefault();
            let email= $('#username_login').val();
            let password= $('#password_login').val();
            smartAxiosLogin.post("/login",{ email:email, password:password })
            .then(function (response) {
                if(response.status==200){
                    smartAxios.get("/profile").then(function(response){console.log(response)}).catch(function(error){console.log(error)});
                }
            })
            .catch(function (error) {
                console.log(error);
            }); 
        });

Я обычно сохраняю accessToken в httpOnly cookie и передаю его через запросы, но в этой ситуации, когда вход и профиль находятся на двух разных поддоменах, вызов profile никогда не получает cookie и, следовательно, возвращает 401 (неавторизован).

На сервере cookies устанавливаются следующим образом:

res.cookie('accessToken', token, { maxAge: 3600000, httpOnly: false, secure: true, Domain: '.mycooldomain.com', Path: "https://stackoverflow.com/", SameSite: 'None' });

res.cookie('refreshToken', _token, { maxAge: 86400000, httpOnly: true, secure: true, Domain: '.mycooldomain.com', Path: "https://stackoverflow.com/", SameSite: 'None' });

Что я делаю не так? Все работает нормально, если вход и профиль находятся на одном и том же конечном API.

Ответ или решение

Для успешной передачи HTTP cookie между различными поддоменами, необходимо правильно настроить параметры cookie и убедиться, что ваши запросы к API выполняются с правильными заголовками. Давайте рассмотрим ваши настройки и проблемы более подробно.

Ваши текущие параметры для установки cookie выглядят следующим образом:

res.cookie('accessToken', token, { 
    maxAge: 3600000, 
    httpOnly: false, 
    secure: true, 
    Domain: '.mycooldomain.com', 
    Path: 'https://stackoverflow.com/', 
    SameSite: 'None' 
});

res.cookie('refreshToken', _token, { 
    maxAge: 86400000, 
    httpOnly: true, 
    secure: true, 
    Domain: '.mycooldomain.com', 
    Path: 'https://stackoverflow.com/', 
    SameSite: 'None' 
});

Ошибки и рекомендации:

  1. Path: Значение Path у вас установлено как https://stackoverflow.com/, что неверно. Оно должно представлять путь на сервере, где cookie будут доступны. Если вы хотите, чтобы cookie были доступны на всех поддоменах, задайте Path: '/'.

  2. httpOnly и secure: Убедитесь, что ваши cookie действительно должны быть httpOnly, если они должны использоваться только для серверных запросов. Для secure убедитесь, что у вас установлено SSL, иначе cookie не будут передаваться (если вы тестируете на локальном хосте, это может быть проблемой).

  3. SameSite: Убедитесь, что вы правильно настраиваете SameSite. Параметр None необходимо устанавливать в сочетании с secure, иначе браузеры будут блокировать cookie.

2. Настройка axios

В вашем коде используется axios с параметром withCredentials: true. Это правильная настройка, которая позволяет передавать cookie в запросах к другому поддомену. Убедитесь, что ваше окружение поддерживает работу с CORS:

smartAxiosLogin.defaults.withCredentials = true;
smartAxios.defaults.withCredentials = true;

На серверной стороне вам нужно убедиться, что ваши заголовки CORS настроены правильно, и что сервер разрешает использование cookie:

app.use(cors({
    origin: 'https://mycooldomain.com',
    credentials: true // Эта опция позволяет передавать cookie
}));

3. Пример исправленного кода

Вот как нужно настроить установку cookie и вызовы с использованием axios:

Серверная часть (Node.js)

res.cookie('accessToken', token, { 
    maxAge: 3600000, 
    httpOnly: false, 
    secure: true, 
    domain: '.mycooldomain.com', 
    path: '/', // Исправлено
    sameSite: 'None' // Убедитесь, что secure true
});

res.cookie('refreshToken', _token, { 
    maxAge: 86400000, 
    httpOnly: true, 
    secure: true, 
    domain: '.mycooldomain.com', 
    path: '/', // Исправлено
    sameSite: 'None' // Убедитесь, что secure true
});

Клиентская часть (JavaScript)

$("#login_form").submit(function(e) {
    e.preventDefault();
    let email = $('#username_login').val();
    let password = $('#password_login').val();

    smartAxiosLogin.post("/login", { email: email, password: password })
    .then(function(response) {
        if(response.status === 200) {
            smartAxios.get("/profile")
            .then(function(response) {
                console.log(response);
            })
            .catch(function(error) {
                console.log(error);
            });
        }
    })
    .catch(function(error) {
        console.log(error);
    }); 
});

Итог

При выполнении вышеуказанных рекомендаций, вы должны получить возможность передавать cookie между поддоменами без ошибок авторизации. Убедитесь, что ваш сервер настроен правильным образом в соответствии с CORS и cookie настройками.

Оцените материал
Добавить комментарий

Капча загружается...