Angular2:对节点服务器的PUT请求不起作用-身份验证丢失

时间:2019-02-18 19:49:49

标签: javascript node.js angular authentication server

我在客户端使用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
        }
      });
    }
  });

1 个答案:

答案 0 :(得分:1)

在没有深入研究auth标头的情况下,我看到了一个非常明显的问题,我认为这可能是造成您麻烦的原因。

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

GET请求随身携带尸体。

PUT请求携带尸体。

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

为了紧跟其后, http.put的方法签名接受3个参数:urlbodyoptions,而http.get的方法签名仅接受2:urloptions

如果您查看示例,则对于http.put,您将this.httpOptions作为 second 参数而不是第三个参数,因此Angular将您的{{1} }对象作为options请求正文。这就是为什么您有一个有效的示例和一个无效的示例的原因。工作示例是PUT

解决方案?只需将其他内容作为请求主体放在第二个参数中,然后将GET向下移至第三个参数槽即可。如果您不关心它是什么,只需使用空对象:this.options

因此您的请求应如下所示:

{}

至少,这应该将return this.http .put(this.domain + 'api/appointments/' + id + '/cancel', {}, this.options) 中的所有内容正确发送到服务器。现在,this.options中的内容是否正确是另一个故事。

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