Angular2: запрос PUT к Node-Server не работает - аутентификация потеряна

Я использую Angular2 на стороне клиента и сервер node-express в качестве бэкэнда. Узел-сервер работает как промежуточное программное обеспечение API, а также как моя служба аутентификации. Пользовательские запросы должны содержать действительный токен JWT для выполнения запросов на узле-сервере.

Все мои функции GET и другие функции PUT работают правильно. Я написал новый, который просто должен удалить идентификатор в стороннем API, а не удалить.

Кроме того, мой сервер node-express в некоторых моментах отправляет клиенту пользовательские сообщения об ошибках. Это касается моей проблемы: всякий раз, когда я запускаю свою последнюю функцию PUT, мой сервер отвечает: «Токен не предоставлен». Это происходит, когда пользователь не вошел в систему на стороне клиента.

Как я уже сказал, все мои другие функции работают. this.createAuthenticationHeaders(); необходим для выполнения действительного запроса на стороне сервера. Но это реализовано.

Другими словами, аутентификация между клиентом и сервером теряется, и я получаю собственное сообщение об ошибке: "Токен не предоставлен".

Назначение-Detail.Component.ts

cancelAppointment() {
    this.authService.getProfile().subscribe(profile => {
      this.username = profile.user.username; // Set username
      this.email = profile.user.email; // Set e-mail
      if (profile.user.email) {
        this.apiService.cancelUserAppointment(this.id).subscribe(data => {
          console.info(this.id);
          if (!data.success) {
            this.messageClass = 'alert alert-danger'; // Set error bootstrap class
            this.message = data.message; // Set error message
          } else {
            this.messageClass = 'alert alert-success'; // Set success bootstrap class
            this.message = data.message; // Set success message
            // After two seconds, navigate back to blog page
          }
        });
      }
    });
  }

Служба API

cancelUserAppointment(id) {
    this.createAuthenticationHeaders();
    console.info('API SERVICE ' + id);
    return this.http
      .put(this.domain + 'api/appointments/' + id + '/cancel', this.options)
      .map(res => res.json());
  }

Функции службы API, которые работают

getCertificatesByUser(email) {
    this.createAuthenticationHeaders();
    return this.http
      .get(this.domain + 'api/user/' + email + '/certificates', this.options)
      .map(res => res.json());
  }

Маршрут сервера к стороннему API

  router.put('/appointments/:id/cancel', (req, res) => {
    console.info('hi');
    var id = req.params.id;
    const url = process.env.acuityUri + '/appointments/' + id + '/cancel';
    console.info(id);
  });

ПО промежуточного слоя аутентификации

router.use((req, res, next) => {
    const token = req.headers['authorization']; // Create token found in headers
    // Check if token was found in headers
    if (!token) {
      res.json({
        success: false,
        message: 'No token provided'
      }); // Return error
    } else {
      // Verify the token is valid
      jwt.verify(token, config.secret, (err, decoded) => {
        // Check if error is expired or invalid
        if (err) {
          res.json({
            success: false,
            message: 'Token invalid: ' + err
          }); // Return error for token validation
        } else {
          req.decoded = decoded; // Create global variable to use in any request beyond
          next(); // Exit middleware
        }
      });
    }
  });
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
25
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Не углубляясь в ваши заголовки аутентификации, я вижу довольно вопиющую проблему, которая, как мне кажется, может быть причиной ваших проблем.

Глаголы HTTP REST несут разные «намерения», намерение, о котором мы особенно заботимся в этом случае, заключается в том, должен ли ваш запрос иметь тело.

GET запросы нет несут с собой тело.

PUT запросы делать содержат тело.

Из-за этого методы запросов angular HttpClient (http.get, http.post и т. д.) имеют разные сигнатуры методов.

Чтобы перейти к делу, Сигнатура метода http.put принимает 3 параметра: url, body и options, тогда как сигнатура метода http.get принимает только 2: url и options.

Если вы посмотрите на свой пример, для http.put вы предоставляете this.httpOptions в качестве параметра второй вместо третьего, поэтому Angular упаковывает ваш объект options в тело запроса PUT. Вот почему у вас есть рабочий пример и нерабочий пример; рабочий пример - GET!

Решение? Просто поместите что-нибудь еще в качестве тела запроса во второй параметр и переместите this.options вниз в слот третьего параметра. Если вам все равно, что это такое, просто используйте пустой объект: {}.

Таким образом, ваш запрос должен выглядеть так:

return this.http
      .put(this.domain + 'api/appointments/' + id + '/cancel', {}, this.options)

По крайней мере, это должно правильно отправлять все, что находится в this.options, на сервер. Теперь, правильно ли то, что в this.options, это другая история.

Пример вызова PUT из документации Angular: https://angular.io/guide/http#making-a-put-request

Это вызвало ошибку! Спасибо за ваше объяснение, имеет смысл для меня. :)

dmnktoe 18.02.2019 21:39

Другие вопросы по теме