我在客户端使用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
}
});
}
});
答案 0 :(得分:1)
在没有深入研究auth标头的情况下,我看到了一个非常明显的问题,我认为这可能是造成您麻烦的原因。
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
作为 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