javascript - HTTP 调用由于另一个方法调用而被取消,如何强制阻止第二次调用,直到收到 HTTP 响应?
问题描述
我正在为 oauth2 做授权代码流,我在这里做错了,但我无法真正检测到..
这是我的代码
在 app.js 中
myService.setup().then(function(){...
在 service.js 中
var service = {
setup(options) {
this.processData();
return this.getToken(options);
},
processData(data) {
let response = this._extractURLParams(window.location.href)
if (response.hasOwnProperty("code")) {
return this.handleAuthorizationCode(responseResult);
},
handleAuthorization(codeObject) {
var service= this;
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open("POST", /token, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
var params = 'grant_type=authorization_code&code=' + codeObject.code + '&client_id=client_id&client_secret=secret&redirect_uri=' + codeObject.redirectURi;
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var responseData = JSON.parse(this.response);
resolve(service.storeToken(responseData));
}
};
xhr.send(params);
});
},
getToken(options) {
let service = this;
return new Promise(function (resolve, reject) {
if(// localStorage has a token) {
resolve(localStorage.getToken()) //dummy text, real code here
} else {
resolve(service.handleRedirectionsFlow(options));
})
},
发生的情况如下
1)当我访问我的应用程序时,我调用 myService.setup()
2)setup()方法会调用processData(),由于url为空,if条件不会通过,所以调用getToken()
3) getToken() 将调用一个方法,该方法将构建一个 url 并将位置更改为它,以便我们通过授权服务器上的表单进行身份验证,然后我们将在使用代码进行身份验证后重定向回应用程序!
4) 身份验证后,我们将重定向到应用程序,例如 'url?code=abcasdasdsfdasifsfsfs
5) 现在,processData() 将检测到 url 具有 code 属性,我们将调用 handleAuthorizationCode
6)handleAuthorizationCode 将简单地进行发布请求以获取令牌,并且 onReadyStateChange 我们将调用另一个方法来存储令牌。
7) 现在,当我们从 setup() 调用 getToken() 时,此时尚未从上一个方法触发 onreadystatechange,导致我们重做重定向以再次进行身份验证,然后令牌请求被取消并且我们从不存储它..
有人可以帮我知道我应该在哪里添加额外的承诺并解决它,以便在触发 onreadystatechange 并存储令牌以避免无限循环之后调用 getToken() 吗?
谢谢
解决方案
如果无法运行它很难知道,但是这个怎么样?
var service = {
setup(options) {
return this.processData()
.then(token => token || this.getToken(options));
},
processData(data) {
const response = this._extractURLParams(window.location.href);
return response.hasOwnProperty("code")
? this.handleAuthorizationCode(responseResult)
: Promise.resolve();
},
handleAuthorization(codeObject) {
var service = this;
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open("POST", /token, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
var params = 'grant_type=authorization_code&code=' + codeObject.code + '&client_id=client_id&client_secret=secret&redirect_uri=' + codeObject.redirectURi;
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var responseData = JSON.parse(this.response);
resolve(service.storeToken(responseData));
}
};
xhr.send(params);
});
},
getToken(options) {
let service = this;
return new Promise(function(resolve, reject) {
if (localStorageHasToken) {
resolve(localStorage.getToken()) //dummy text, real code here
} else {
resolve(service.handleRedirectionsFlow(options));
}
});
}
};
本质上,我们processData
总是返回一个 Promise,即使它是一个立即解决的 Promise,并且setup
我们在调用之前等待processData()
Promise 解决getToken
。
我不确定返回什么,但如果令牌已经存储service.storeToken(responseData)
,您可以使用它完全跳过调用。getToken
推荐阅读
- guacamole - 鳄梨酱:权限被拒绝单击仅与子组的连接
- celery - 跟踪和弦成员的进度
- javascript - 如何在 cypress 中根据环境使用两个不同的 json 数据文件
- python - DistilBERT 预测输出 - “TypeError:只有大小为 1 的数组可以转换为 Python 标量”
- php - 有条件地加载 laravel api 资源
- javascript - 如何在视频加载时显示骨架?
- vba - 如何在 Microsoft Word 中搜索和突出显示多个术语?
- python - 有没有办法告诉我whatsapp中的消息是否被标记(或回复)
- postgresql - pgAudit 未在 GCP Cloud SQL 中记录任何内容
- java - 如何访问 QueryDSL QuerydslBinderCustomizer 中的跨字段值?