头图

源代码如下:

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)场景下使用。下面我将逐步解释这段代码的逻辑。

  1. 初始化变量:

    var mRemoteSystems,
        aRemoteLogoutPromises = [];

    在这里,声明了两个变量 mRemoteSystemsaRemoteLogoutPromisesmRemoteSystems 用于存储远程系统的信息,而 aRemoteLogoutPromises 是一个用于存储远程注销操作的 Promise 数组。

  2. 移除事件监听器:

    if (fnStorageEventListener) {
        window.removeEventListener('storage', fnStorageEventListener);
    }

    这段代码通过判断是否存在 fnStorageEventListener 函数来确定是否需要移除本地存储事件监听器。在这里,移除了与 fnStorageEventListener 相关联的 storage 事件监听器,该监听器可能是为了处理 IE 浏览器发送的本地存储事件。

  3. 设置本地存储项:

    sap.ushell.utils.localStorageSetItem(sSessionTerminationKey, "pending");

    设置了本地存储中的一个项,其键为 sSessionTerminationKey,值为字符串 "pending"。这个操作可能用于在本地标记会话终止的状态。

  4. 调用 suppressOData 函数:

    suppressOData();

    执行了一个名为 suppressOData 的函数。根据函数名,这可能是用于抑制 OData 请求的操作,以确保在注销期间不发送不必要的请求。

  5. 获取远程系统信息:

    mRemoteSystems = getRemoteSystems();

    调用了一个名为 getRemoteSystems 的函数,用于获取远程系统的信息,并将其存储在 mRemoteSystems 中。

  6. 迭代远程系统并执行注销操作:

    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 数组中。如果创建适配器或注销操作失败,会记录相应的警告信息,并从本地存储中移除相关的项。

  7. 等待所有远程系统注销完成:

    jQuery.when.apply(jQuery, aRemoteLogoutPromises).done(logoutLogonSystem);

    使用 jQuery.when 函数等待所有的远程系统注销 Promise 完成。一旦所有的 Promise 都完成,将调用 logoutLogonSystem 函数。

  8. 处理进一步的远程系统:

    if (typeof oAdapter.addFurtherRemoteSystems === 'function') {
        oAdapter.addFurtherRemoteSystems().always(federatedLogout);
    } else {
        federatedLogout();
    }

    检查适配器是否提供了 addFurtherRemoteSystems 方法,如果是,则调用该方法获取进一步的远程系统信息,并始终执行 federatedLogout 函数。如果适配器不提供此方法,则直接调用 federatedLogout 函数。

  9. 返回 Promise:

    return oDeferred.promise();

    最后,返回一个 Promise 对象,该对象可能用于链式调用或其他异步处理。

总体而言,这段代码实现了一种联邦式登出的逻辑,通过迭代远程系统,调用相应的适配器执行注销操作,然后等待所有远程系统注销完成后再执行进一步的处理。这样的设计适用于多系统环境下的用户注销场景,确保用户在所有系统中都被正确注销。


注销
1k 声望1.6k 粉丝

invalid