将ExtJS 6.20与一堆具有固定网址的模型一起使用到API,如下所示:
Ext.define('Admin.model.Patient', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.proxy.Rest',
'Ext.data.schema.Association'
],
fields: [
{ name: 'id', type: 'string' },
{ name: 'mrn', type: 'string' },
{ name: 'birth_date', type: 'date', format: 'Y-m-d' },
{ name: 'sex', type: 'string' },
{ name: 'first_name', type: 'string' },
{ name: 'last_name', type: 'string' }
],
proxy: {
type: 'ajax',
url: 'http://localhost/patientview/api/read',
reader: {
type: 'json',
rootProperty: ''
}
}
});
问题是,在成功登录之前,需要从API获取身份验证会话cookie,然后才能连接到API的受保护资源。我很容易从HTTP响应中获取会话cookie(并计划将其存储在会话存储中),但我不确定如何将其作为有效负载(如extraParams
?)传递给代理,特别是因为它是已启动应用程序时已绑定到我的数据模型。
FWIW,为了使用经过身份验证的Cookie测试API,我使用curl
中的cookie参数,如curl -v --cookie "session=XXX" http://0.0.0.0:5000/patientview/api/read
中所示,其中XXX是会话Cookie的值。
由于Set-Cookie
标题是“禁止”对象,因此withCredentials: true
标题通常不可用(例如,参见how to get a cookie from an AJAX response)。
看起来有一种方法可以使用onLoginButton: function() {
var formPanel = this.lookupReference('loginForm'),
form = formPanel.getForm(),
url = 'http://localhost/login_api/';
if (form.isValid()) {
values = form.getValues(true);
console.log(values);
Ext.Ajax.request({
method: 'POST',
cors: true,
withCredentials: true,
useDefaultXhrHeader: false,
url: url,
params: values, //username and password
headers: {
'Accept': 'application/json'
},
disableCaching: false,
success: function (response) {
json = Ext.decode(response.responseText);
test = response.getAllResponseHeaders();
console.log('json');
console.log(json);
console.log(test);
console.log(response);
if (response.status === 201) {
console.log(json.items);
}
else {
Ext.MessageBox.alert('Error', response.message);
}
}
});
}
},
通过后续请求提供这些凭据
关键字(请参阅getting extjs to work with cors and cookies on chrome)。
我按照以下方式将我的登录修改为API:
responseHeaders
但是,即使这样,它也没有按预期工作。我假设,因为withCredentials
中没有第三方Cookie,并且因为它们应该通过Patient
关键字注入,所以还需要做其他事情。
FWIW,我的ExtJS应用程序的路径为http://localhost/test/,而Flask / API可在http://localhost/下访问...(为了消除任何跨域问题,我在本地运行这些一个nginx / uwsgi web / app服务器,通过端口80提供服务。我顺利登录,顺便说一句。我只是不确定如何将凭据传递给我的其他API调用(例如,上面的success: function (response) {
if (response.status === 201) {
console.log(json.items);
Ext.Ajax.request({
url: 'http://localhost/patientview/api/read',
method: 'GET',
cors: true,
useDefaultXhrHeader: false,
withCredentials: true,
success: function(response) {
var result = Ext.decode(response.responseText);
console.log(result);
}
});
}
}
模型)。
注意:如果我在我的第一个Ext.request.Ajax调用成功回调中将另一个AJAX调用(根据上面的博客文章)嵌套到http://localhost/patientview/api/read,它可以工作,按照
cors
但是,虽然这是概念证明这是可行的,但它并没有解决如何将凭证注入我的预定义模型的问题。
修改
我删除了withCredentials
和Ext.request.Ajax
选项,因为网络应用和api位于同一个域等。它确实可以正常工作。另外,我测试了另一个我调用Ext.define('Admin.view.main.MainModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.main',
stores: {
patients: {
model: 'Admin.model.Patient',
autoLoad: true
}
}
});
的函数,并且通过从浏览器自动获取凭据来实现这一功能。
它仍然无法使用模型代理(它们都定义类似于上面的代码;相同的协议,相同的域,相同的端口等)
值得注意的是,如果我刷新浏览器,那么数据可供所有使用ajax代理绑定到模型的不同商店使用(这是有道理的)。我想知道在登陆成功后是否有办法重新加载绑定到模型的商店?
我的商店按照以下方式绑定到模型视图:
bind: {
store: '{patients}'
},
然后,例如,通过数据绑定,它通过绑定命令被送到下拉组合框:
<div ng-app="productController" ng-controller="productCtrl" class="row-fluid">
<div class="col-md-12">
<div class="form-group">
<div class="input-group mb-2 mr-sm-2 mb-sm-0">
<div class="input-group-addon">
<i class="fa fa-pencil"></i>
</div>
<input ng-disabled="product.disabled" type="text" ng-model="description[0]" name="description" class="form-control" placeholder="Description..." required>
<div class="input-group-addon">
<a ng-click="addfield()" class="add-field">
<i class="fa fa-plus"></i>
</a>
</div>
</div>
<div ng-repeat="item in inputs track by $index">
<div class="input-group mb-2 mr-sm-2 mb-sm-0 repeat-input">
<div class="input-group-addon">
<i class="fa fa-pencil"></i>
</div>
<input ng-disabled="product.disabled" type="text" name="description" ng-model="description[$index+1]" class="form-control" placeholder="Description..." required>
</div>
</div>
</div>
</div>
{{description}}
</div>
如果我要重新加载商店,这究竟会在哪里?我对ExtJS中的数据绑定有点新意。
答案 0 :(得分:0)
要全局设置授权Cookie,您可以尝试使用
Ext.util.Cookies.set('session', token);
但是,如果资源位于不同的端点上,则会失败,因为cookie是为index.html所在的端点保存的,并且不会提交给其他端点。在这种情况下,您必须检查远程API如何获取令牌。
由于存在这些跨域问题,如果您使用的是OAuth等标准化身份验证方法,则该令牌通常会被视为承载令牌,这意味着您可以在全局范围内为所有Ajax调用设置一次,像这样:
Ext.Ajax.setDefaultHeaders({
'Authorization': 'Bearer ' + token,
'Accept': 'application/json'
});
答案 1 :(得分:0)
我最终终于使用了这个的修改版本:ExtJS login app ...它比基于用户会话管理路由行为更容易实现。现在,所有带有ajax代理的模型都不会加载,直到创建主视图,这只发生在我的AJAX身份验证请求中成功回调之后。