源代码如下:
function federatedLogout() {
var mRemoteSystems,
aRemoteLogoutPromises = [];
if (fnStorageEventListener) {
// IE sends localStorage events also to the issuing window, -
// this is not needed hence we remove the listener in general at that point
window.removeEventListener('storage', fnStorageEventListener);
}
sap.ushell.utils.localStorageSetItem(sSessionTerminationKey, "pending");
suppressOData();
mRemoteSystems = getRemoteSystems();
Object.keys(mRemoteSystems).forEach(function (sAlias) {
try {
aRemoteLogoutPromises.push(
createAdapter("Container", mRemoteSystems[sAlias]).logout(false)
);
} catch (e) {
jQuery.sap.log.warning("Could not create adapter for " + sAlias,
e.toString(), "sap.ushell.Container");
}
oLocalStorage.removeItem(sRemoteSystemPrefix + sAlias);
});
// wait for all remote system logouts to be finished
// Note: We use done() and not always(), and we require all adapters to resolve
// their logout(false) in any case. If we use always() and any adapter's promise is
// rejected, the deferred object from when() is *immediately* rejected, too. Then
// the redirect happens before all remote logouts are finished.
// TODO force logoutLogonSystem after timeout?
jQuery.when.apply(jQuery, aRemoteLogoutPromises).done(logoutLogonSystem);
}
if (typeof oAdapter.addFurtherRemoteSystems === 'function') {
oAdapter.addFurtherRemoteSystems().always(federatedLogout);
} else {
federatedLogout();
}
return oDeferred.promise();
};
这段 SAP UI5 源代码是实现一个名为 federatedLogout
的函数,该函数用于执行联邦式登出(federated logout)操作。联邦式登出是指在多个远程系统中注销用户,通常在单点登录(SSO)场景下使用。下面我将逐步解释这段代码的逻辑。
初始化变量:
var mRemoteSystems, aRemoteLogoutPromises = [];
在这里,声明了两个变量
mRemoteSystems
和aRemoteLogoutPromises
。mRemoteSystems
用于存储远程系统的信息,而aRemoteLogoutPromises
是一个用于存储远程注销操作的 Promise 数组。移除事件监听器:
if (fnStorageEventListener) { window.removeEventListener('storage', fnStorageEventListener); }
这段代码通过判断是否存在
fnStorageEventListener
函数来确定是否需要移除本地存储事件监听器。在这里,移除了与fnStorageEventListener
相关联的storage
事件监听器,该监听器可能是为了处理 IE 浏览器发送的本地存储事件。设置本地存储项:
sap.ushell.utils.localStorageSetItem(sSessionTerminationKey, "pending");
设置了本地存储中的一个项,其键为
sSessionTerminationKey
,值为字符串 "pending"。这个操作可能用于在本地标记会话终止的状态。调用
suppressOData
函数:suppressOData();
执行了一个名为
suppressOData
的函数。根据函数名,这可能是用于抑制 OData 请求的操作,以确保在注销期间不发送不必要的请求。获取远程系统信息:
mRemoteSystems = getRemoteSystems();
调用了一个名为
getRemoteSystems
的函数,用于获取远程系统的信息,并将其存储在mRemoteSystems
中。迭代远程系统并执行注销操作:
Object.keys(mRemoteSystems).forEach(function (sAlias) { try { aRemoteLogoutPromises.push( createAdapter(`Container`, mRemoteSystems[sAlias]).logout(false) ); } catch (e) { jQuery.sap.log.warning(`Could not create adapter for ${sAlias}`, e.toString(), `sap.ushell.Container`); } oLocalStorage.removeItem(sRemoteSystemPrefix + sAlias); });
通过迭代
mRemoteSystems
中的远程系统,使用createAdapter
函数创建适配器,并调用其logout
方法执行注销操作。成功创建的注销 Promise 被添加到aRemoteLogoutPromises
数组中。如果创建适配器或注销操作失败,会记录相应的警告信息,并从本地存储中移除相关的项。等待所有远程系统注销完成:
jQuery.when.apply(jQuery, aRemoteLogoutPromises).done(logoutLogonSystem);
使用
jQuery.when
函数等待所有的远程系统注销 Promise 完成。一旦所有的 Promise 都完成,将调用logoutLogonSystem
函数。处理进一步的远程系统:
if (typeof oAdapter.addFurtherRemoteSystems === 'function') { oAdapter.addFurtherRemoteSystems().always(federatedLogout); } else { federatedLogout(); }
检查适配器是否提供了
addFurtherRemoteSystems
方法,如果是,则调用该方法获取进一步的远程系统信息,并始终执行federatedLogout
函数。如果适配器不提供此方法,则直接调用federatedLogout
函数。返回 Promise:
return oDeferred.promise();
最后,返回一个 Promise 对象,该对象可能用于链式调用或其他异步处理。
总体而言,这段代码实现了一种联邦式登出的逻辑,通过迭代远程系统,调用相应的适配器执行注销操作,然后等待所有远程系统注销完成后再执行进一步的处理。这样的设计适用于多系统环境下的用户注销场景,确保用户在所有系统中都被正确注销。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。