#ajax #go #cors #jwt #setcookie
#ajax #Вперед #cors #jwt #setcookie
Вопрос:
Я создал API в golang. Серверная часть и интерфейс работают на разных серверах. Когда я тестирую API с помощью POSTMAN, все работает нормально, и я получаю файл cookie, содержащий токен jwt, но когда я выполняю запрос от интерфейса, файл cookie не принимается.
Вот промежуточное программное обеспечение для обработки CORS:
func corsHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// origin := r.Header.Get("Origin")
w.Header().Set("Access-Control-Allow-Origin", "http://localhost:5000")
if r.Method == "OPTIONS" {
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, Authorization, access-control-allow-origin")
return
}
h.ServeHTTP(w, r)
})
}
Ниже приведен генератор файлов cookie:
jwtCookie := amp;http.Cookie{
Name: "jwtToken",
Secure: false,
HttpOnly: true,
Value: tokenString,
Expires: expiryTime,
}
http.SetCookie(w, jwtCookie)
w.Header().Add("Access-Control-Allow-Credentials", "true")
w.WriteHeader(http.StatusOK)
Ниже приведен запрос ajax:
$.ajax({
type: 'POST',
url: 'http://localhost:8080/api/signin',
data: JSON.stringify({
"username": $('#username').val(),
"password": $('#password').val()
}),
xhrFields: { withCredentials: true },
contentType: "application/json",
dataType: "json",
success: function(data) {
console.log(data);
},
error: function(message) {
console.log(message.responseJSON);
}
});
В firefox заголовок ответа выглядит следующим образом:
Как вы можете видеть на изображении 1, файл cookie принимается в заголовке, но он не отображается в хранилище
В Chrome заголовок ответа выглядит так: в Chrome не отображается файл cookie
Я застрял на этом довольно долго. Любая помощь была бы ценной 🙂
Комментарии:
1. Разрешенный источник вашего CORS не совпадает с URL-адресом в вашем JavaScript — обслуживаются ли ваш API и пользовательский интерфейс с одного и того же порта?
2. Нет, они обслуживаются на разных портах. Интерфейс: localhost: 5000, серверная часть: localhost: 8080
Ответ №1:
Мне пришлось добавлять w.Header().Add("Access-Control-Allow-Credentials", "true")
для всех запросов, а не только для предварительного запроса параметров, а также оказалось, что chrome не показывал файл cookie в хранилище, но он присутствовал и работал, как ожидалось, позже я проверил в firefox, и файл cookie был виден в хранилище.
Ответ №2:
В ответе вашего сервера установите HttpOnly
значение false, а в chrome перейдите в консоль и введите document.cookie
. Вы должны увидеть файл cookie, установленный сервером.
Другой вариант — оставить HttpOnly
значение true. В Chrome откройте инструменты разработчика, нажмите на Application
вкладку, вы должны увидеть Cookies
ниже Storage
. Нажмите Cookies
, и вы увидите файл cookie, установленный сервером.