Вопрос или проблема
Предположим, у меня есть 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 выполняются с правильными заголовками. Давайте рассмотрим ваши настройки и проблемы более подробно.
1. Установка cookie
Ваши текущие параметры для установки 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'
});
Ошибки и рекомендации:
-
Path: Значение
Path
у вас установлено какhttps://stackoverflow.com/
, что неверно. Оно должно представлять путь на сервере, где cookie будут доступны. Если вы хотите, чтобы cookie были доступны на всех поддоменах, задайтеPath: '/'
. -
httpOnly и secure: Убедитесь, что ваши cookie действительно должны быть
httpOnly
, если они должны использоваться только для серверных запросов. Дляsecure
убедитесь, что у вас установлено SSL, иначе cookie не будут передаваться (если вы тестируете на локальном хосте, это может быть проблемой). - 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 настройками.