Я отправляю файл cookie в ответ из серверной части узла в свой интерфейс после подписания jwt. На вкладке сети в интерфейсе виден set-cookie и отображается файл cookie, но на вкладке приложения файл cookie не отображается. Почему это?
Код внутренней функции для отправки файлов cookie:
import jwt from 'jsonwebtoken'
export const generateTokenAndSetCookie = (userId , res)=>{
const token = jwt.sign({userId} , process.env.JWT_SECRET , {
expiresIn : '15d',
} )
res.cookie("jwt" , token , {
httpOnly: false,
secure: true,
sameSite:'none'
})
}
Код CORS:
app.use(cors({credentials : true , origin : 'http://localhost:3000'}));
Код внешнего интерфейса для отправки запроса POST для входа в систему:
const handleSubmit = async (e) => {
e.preventDefault();
// console.info(formData);
if (!formData.password || !formData.username) {
toast("Please Fill All the Fields !");
return;
}
try {
setLoading(true);
const res = await fetch(`${PROXY_URL}/api/auth/login`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(formData),
});
const data = await res.json();
if (!res.ok){
toast.error(data.error || "Failed to Login");
setLoading(false);
return;
}
setLoading(false);
setIsError(false);
// console.info(data);
console.info(document.cookie);
toast.success("User Logged In Successfully !");
setFormData({
username: "",
password: "",
})
} catch (error) {
setIsError(true);
console.info(error);
}
};
Изображение вкладки «Сеть»:
Вкладка «Приложение» Изображение одновременно:
Что делать ?
Какова ценность PROXY_URL
? Он должен быть того же происхождения, что и ваш сайт.
@Адитья Нагаре, ты можешь это решить?
Установите secure
на false
, возможно, используя переменную среды, чтобы различать среду разработки и рабочую среду.
Это связано с тем, что опция secure
гарантирует, что файлы cookie отправляются только через безопасное соединение, которое указано в адресе как «https://». В режиме разработки ваше соединение небезопасно, поскольку вы получаете доступ с «http://localhost».
import jwt from 'jsonwebtoken'
export const generateTokenAndSetCookie = (userId , res)=>{
const token = jwt.sign({userId} , process.env.JWT_SECRET , {
expiresIn : '15d',
} )
res.cookie("jwt" , token , {
httpOnly: false,
secure: process.env.NODE_ENV === 'production',
sameSite:'none'
})
}
я тоже так сделал, но все равно не работает.
О черт. Можете ли вы попробовать включить учетные данные в свой запрос на выборку?
Я тоже это сделал.
Хороший ответ, но для localhost есть исключение.
что делать тогда?
Похоже, у вас возникли проблемы с настройкой файлов cookie, поэтому давайте попробуем использовать все параметры файлов cookie, поскольку ранее у меня была подобная проблема.
// Set cookie options
const cookieOptions = {
// httpOnly: true, // Prevents client-side access to the cookie
sameSite: "None", // Allows cross-origin requests to include the cookie
secure: true, // Ensures the cookie is only sent over HTTPS
domain: "192.168.99.62", // Set to your server's domain, do not type localhost, use your IP instead
path: "/", // Cookie is valid for all routes
expires: new Date(Date.now() + 3600000), // Cookie expires in 1 hour (adjust as needed)
};
// Set the cookie
res.cookie("authToken", jwtToken, cookieOptions);
все еще не работает
какой браузер вы используете?
хром. Но если я использовал другой, он все равно выдает ту же ошибку.
Со мной это тоже очень часто случается. Можете ли вы попытаться переписать вызов API, чтобы в учетные данные были включены.
const res = await fetch(`${PROXY_URL}/api/auth/login`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(formData),
credentials: 'include'
});
Я также думаю, что вам, возможно, придется настроить сервер следующим образом:
res.cookie("jwt" , token , {
httpOnly: true,
// I think if server needs to set a cookie it must be httpOnly
secure: process.env.NODE_ENV === 'production',
sameSite:'none'
})
Кроме того, эти два поста могут вам помочь:
Кажется, что ваш интерфейс и серверная часть не находятся в одном домене (или порту). Когда вы устанавливаете файл cookie со своего бэкэнда, он помещает его в домен вашего бэкэнда. Чтобы использовать другой домен, вам необходимо указать его явно:
res.cookie("jwt" , token , {
httpOnly: false,
secure: true,
sameSite:'none',
domain: 'http://localhost:3000',
})
Я получил ответ. При отправке запроса на выборку на сервер я не передал заголовок:
headers: {
"Content-Type": "application/json",
},
После передачи этого заголовка все заработало нормально.
ты уверен, что везде используешь
localhost
, а не127.0.0.1
?