Когда я выполняю POST-запрос в golang api с использованием POSTMAN, я успешно получаю токен jwt в виде файла cookie, но когда я делаю это из браузера, я не получаю cookie

#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, установленный сервером.