尝试从 api 获取令牌时节点获取的错误行为
Posted
技术标签:
【中文标题】尝试从 api 获取令牌时节点获取的错误行为【英文标题】:incorrect behaviour of node-fetch while trying to get token from an api 【发布时间】:2018-01-13 09:16:27 【问题描述】:我想使用一些节点获取代码连接到外部 api。我的代码首先发送登录详细信息,并且应该从 api 接收令牌。然后这个令牌用于以后的所有通信。
代码如下:
import fetch from 'node-fetch';
function getTokenForAuth(info)
try
var auth_token = '';
fetch(api_url + '/api/api-token/',
method: 'POST',
body: JSON.stringify(info),
headers:
'Content-Type': 'application/json',
'Accept': 'application/json'
)
.then(function(res)
return res.json();
)
.then(function(json)
auth_token = json;
)
return auth_token.token;
catch (e)
console.log('[-] Error: Token Not Received');
console.log('[!] Exception: ' + e);
function getJSONFromRelativeURL(relativeURL, info)
return fetch(`$api_url$relativeURL`,
method: 'GET',
headers:
'Content-Type': 'application/json',
'Authorization': 'Token ' + getTokenForAuth(info)
)
.then(function(res)
console.log(res);
return res.json();
)
.then(function(json)
console.log(json);
)
在getJSONFromRelativeURL()
函数的请求标头中,如果我对令牌进行硬编码,我会得到正确的结果。但是如果我现在运行代码,我会收到一条错误消息: detail: 'Invalid token.'
。
我认为这是因为 fetch 函数中 promise 的异步性质,因此它有时无法在 getJSONFromRelativeURL()
被调用之前及时发送令牌。我不确定这个假设,也不知道如何纠正。
【问题讨论】:
getTokenForAuth
返回一个承诺对象。所以你没有设置授权头。尝试控制它,您将看到一个对象而不是令牌。必须调用getTokenForAuth
并在其中.then()
调用getJSONFromRelativeURL
函数。这样您就可以将令牌作为字符串。还必须从 then 内部而不是外部返回令牌。
反正我是第一个回答的。是什么让您不理解我的回答,以便我改进?
我刚刚选择了另一个答案,因为它的代码更好地放在一起,他还回答了我的假设(我不确定)。我认为,回首往事,他的答案也以更好的方式与逻辑流程组合在一起(向我展示我做错了什么,然后逐步回答)。
【参考方案1】:
你的问题在这里:
.then(function(json)
auth_token = json;
)
return auth_token.token;
您的 return
语句位于 Promise 链之外。这意味着,在您点击return
时,fetch
请求甚至还没有机会运行。你基本上只是告诉fetch
Promise 链做什么当它确实返回时要做什么。
本质上
我认为这是因为 fetch 函数中 promise 的异步性质,因此它有时无法在调用 getJSONFromRelativeURL() 之前及时发送令牌。
100% 正确。
你需要做的是稍微重组一下:
function getTokenForAuth(info)
return fetch(api_url + "/api/api-token/",
method: "POST",
body: JSON.stringify(info),
headers:
"Content-Type": "application/json",
Accept: "application/json"
).then(function(res)
return res.json();
);
function getJSONFromRelativeURL(relativeURL, info)
return getTokenForAuth(info)
.then(function(token)
return fetch(`$api_url$relativeURL`,
method: "GET",
headers:
"Content-Type": "application/json",
Authorization: `Token $token`
);
)
.then(function(res)
console.log(res);
return res.json();
)
.then(function(json)
console.log(json);
);
【讨论】:
【参考方案2】:尚未对其进行测试,但它看起来类似于以下内容。对于错误处理,在每个链的末尾使用 .catch(()=>) 。
function getTokenForAuth(info)
var auth_token = '';
return fetch(api_url + '/api/api-token/',
method: 'POST',
body: JSON.stringify(info),
headers:
'Content-Type': 'application/json',
'Accept': 'application/json'
)
.then(function(res)
return res.json();
)
function getJSONFromRelativeURL(relativeURL, info, token)
return fetch(`$api_url$relativeURL`,
method: 'GET',
headers:
'Content-Type': 'application/json',
'Authorization': 'Token ' + token
)
.then(function(res)
console.log(res);
return res.json();
)
.then(function(json)
console.log(json);
)
getTokenForAuth(info)
.then((token)=>
return getJSONFromRelativeURL(relativeURL, info, token)
)
【讨论】:
以上是关于尝试从 api 获取令牌时节点获取的错误行为的主要内容,如果未能解决你的问题,请参考以下文章
从 reddit api 获取 api oauth 访问令牌