【问题标题】:Angular2: PUT request to Node-Server doesn't work - authentication lostAngular2:对节点服务器的 PUT 请求不起作用 - 身份验证丢失
【发布时间】:2019-02-18 19:49:48
【问题描述】:

我在客户端使用 Angular2 和一个 node-express 服务器作为我的后端。节点服务器用作 API 中间件,也用作我的身份验证服务。用户请求必须包含有效的 JWT 令牌才能在节点服务器上执行请求。

我所有的 GET 函数和其他 PUT 函数都可以正常工作。我写了一个新的,它应该删除第三方 API 上的 ID,没有。

此外,我的 node-express 服务器有时会向客户端发送自定义错误消息。这就是我的问题,每当我运行最新的 PUT 函数时,我的服务器都会以“未提供令牌”进行响应。当用户未在客户端登录时会发生这种情况。

正如我所说,我的所有其他功能都可以正常工作。 this.createAuthenticationHeaders(); 是在服务器端执行有效请求所必需的。但是已经实现了。

换句话说,客户端和服务器之间的身份验证丢失,我收到自己的错误消息:“未提供令牌”

Appointment-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.log(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.log('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.log('hi');
    var id = req.params.id;
    const url = process.env.acuityUri + '/appointments/' + id + '/cancel';
    console.log(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
        }
      });
    }
  });

【问题讨论】:

    标签: javascript node.js angular authentication server


    【解决方案1】:

    没有对您的身份验证标头进行太多深入研究,我发现一个非常明显的问题,我认为这可能是您遇到问题的原因。

    HTTP REST 动词带有不同的“意图”,在这种情况下我们特别关心的意图是您的请求是否应该有正文。

    GET 请求随身携带尸体。

    PUT 请求携带身体。

    因此,Angular 的HttpClient 请求方法(http.gethttp.post 等)具有不同的方法签名。

    切入正题,http.put 的方法签名接受 3 个参数:urlbodyoptions,而 http.get 的方法签名只接受 2 个参数:@987654332 @ 和 options

    如果您查看您的示例,对于 http.put,您将 this.httpOptions 作为 第二个 参数而不是第三个参数提供,因此 Angular 将您的 options 对象打包为 @987654337 @请求正文。这就是为什么你有一个工作示例和一个非工作示例的原因;工作示例是GET!

    解决方案?只需将其他内容作为请求正文放入第二个参数中,然后将this.options 向下移动到第三个参数槽。如果您不在乎它是什么,只需使用空对象:{}

    所以你的请求应该是这样的:

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

    至少,这应该将this.options 中的任何内容正确发送到服务器。现在this.options 中的内容是否正确是另一回事。

    来自 Angular 文档的示例 PUT 调用:https://angular.io/guide/http#making-a-put-request

    【讨论】:

    • 这导致了错误!谢谢你的解释,对我来说很有意义。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-11
    • 2014-05-07
    • 2023-03-24
    • 2017-06-01
    • 2014-04-06
    相关资源
    最近更新 更多