TL;DR要求用户登录以查看 Durandal 单页应用程序 (SPA) 中的某些页面的良好模式是什么?
我需要一个系统,如果用户试图导航到要求他们登录的“页面”,他们会被重定向到登录页面。在此登录页面上成功进行身份验证后,我希望应用程序将它们重定向到他们之前尝试访问的页面,然后再将它们重定向到登录页面。
我能想到的一种可以实现将用户重定向到登录页面和从登录页面重定向的方法是将 URL 存储到需要在浏览器历史记录中进行身份验证的页面,并在成功进行身份验证后,从登录页面。
执行
我试图实现上述模式,但有一些问题。在main.js
(或之前router.activate()
被调用的任何地方)我保护需要身份验证的路由:
router.guardRoute = function (instance, instruction) {
if (user.isAuthenticated()) {
return true;
} else {
if (instance && typeof (instance.allowAnonymous) === "boolean") {
if (!instance.allowAnonymous) {
/* Use one of the following two methods to store an item in the
browser history. */
/* Add guarded URL to the history and redirect to login page.
* We will navigate back to this URL after a successful login.
*/
if (history.pushState) {
history.pushState(null, null, '#' + instruction.fragment);
}
else {
location.hash = '#' + instruction.fragment;
}
*/
/* This will not work - history is not updated if the fragment
* matches the current fragment.*/
////router.navigate(instruction.fragment, false);
/* The following solution puts in a fragment to the history
* that we do not want the user to see. Is this an
* acceptable solution? */
router.navigate(instruction.fragment + 'LoginRedirect', false);
return router.convertRouteToHash("login");
}
}
return true;
}
};
在shell.js
我添加到登录页面的路由:
return {
router: router,
activate: function () {
router.map([
...
{ route: 'login', title: '', moduleId: 'viewmodels/login', nav: true },
...
]).buildNavigationModel();
return router.activate();
},
...
}
然后我viewmodels/login.js
有代码片段:
if (account.isAuthenticated()) {
router.navigateBack();
}
限制
此方法的一个限制是,它允许用户在经过身份验证并被重定向离开登录页面后导航到登录页面。
此外,使用
router.navigate(instruction.fragment + 'LoginRedirect', false);
我偶尔会LoginRedirect
在 URL 中看到闪现。
一个更严重的限制是用户在登录页面上按回不会被带到前一个(非保护)页面(而是会被带到保护页面,该页面将重定向到登录页面)。
guardRoute
刷新页面似乎也存在错误(请参见此处。这仍然是一个问题吗?
它们是否包含任何标准的 Durandal 模式,这些模式封装了上述行为并且没有与上面列出的类似限制?