迪朗达尔登录页面重定向模式 [英] Durandal login page redirect pattern

查看:176
本文介绍了迪朗达尔登录页面重定向模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TL; DR 什么是需要用户以查看在迪朗达尔单页应用(SPA)某些网页登录的良好格局。

TL;DR What is a good pattern for requiring a user to login in order to view certain pages in a Durandal Single Page Application (SPA)?

我需要一个系统,由此如果用户试图定位到一个页面,要求它们被登录,它们被代替重定向到登录页面。在此登录页面上的成功认证,我会然后像应用程序重定向到它们previously试图访问之前,他们被重定向到登录页面的页面。

I need a system whereby if a user attempts to navigate to a "page" that requires them to be logged in, they are instead redirected to a login page. Upon successfully authenticating on this login page, I would then like the application to redirect them to the page that they previously attempted to access before they were redirected to the login page.

这我能想到其中的可为用户重定向到与从登录页面被实现的一种方法是在URL存储到这需要在浏览器的历史验证页,并在成功验证后,导航回到此历史从登录页面项目。

One method that I can think of which may be implemented for redirecting a user to and from a login page is to store the URL to the page which requires authentication in the browser history and, after successfully authenticating, navigate back to this history item from the login page.

我试图实现上述模式,但有几个问题,用它。在 main.js (或之前的任何地方 router.activate()的叫法)我守卫需要身份验证的路线:

I have attempted to implement the pattern described above but have a few issues with it. In main.js (or anywhere before router.activate() is called) I guard the route which requires authentication:

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 我添加到登录页面的路径:

In shell.js I add a route to the login page:

return {
    router: router,
    activate: function () {
        router.map([
        ...
        { route: 'login', title: '', moduleId: 'viewmodels/login', nav: true },
        ...
        ]).buildNavigationModel();
        return router.activate();
    },
    ...
}

的ViewModels / login.js 然后我有code片断:

In viewmodels/login.js I then have the code snippet:

if (account.isAuthenticated()) {
    router.navigateBack();
} 

限制

这种方法的一个限制是它允许用户向前导航到登录页面他们身份验证和被重定向从登录页面远后

Limitations

One limitation of this method is that it allows the user to navigate forward to the login page after they have authenticated and been redirected away from the login page.

此外,使用

router.navigate(instruction.fragment + 'LoginRedirect', false);

我偶尔看到 LoginRedirect 在URL中闪烁起来。

一个更严重的限制是每个用户pressing回到登录页面上不会被带到previous(非守卫)页面(而是将要采取的谨慎页面,该页面将重定向到登录页面)。

A more serious limitation is that a user pressing back on the login page will not be taken to the previous (non-guarded) page (but instead will be taken to the guarded page, which will redirect to the login page).

这也似乎有与 guardRoute 又让通过刷新页面错误(见的这里。这仍然是一个问题?

It also seems that there is a bug with the guardRoute letting page refreshed through (see here. Is this still an issue?

,他们都封装了上述行为,并没有类似的限制上述所列任何标准迪朗达尔模式?

Are they any standard Durandal patterns which encapsulate the above behaviour and don't have similar limitations as those listed above?

推荐答案

试图实现我的问题描述的导航回的方法我已决定反对使用,因为我上面所描述的限制,这种方法。

Query-string pattern

Attempting to implement the "navigate back" method described in my question I have decided against using this method because of the limitations I have described above.

我在实践中发现,其效果要好得多的方法是将URL传递到需要身份验证作为查询字符串到登录页面,然后可以使用它来向前导航到该URL一旦用户是页面验证。

I have found in practice that a method which works much better is to pass the URL to the page which requires authentication as a query string to the login page, which can then use this to navigate forward to this URL once a user is authenticated.

以下是该方法,该方法我已经采用的实施方案的概要。我仍然渴望了解的人都通过了关于但是迪朗达尔应用程序使用其他登录模式。

Below is an outline of an implementation of this method which I have adopted. I am still keen to learn about any other login patterns that people have adopted for use in Durandal applications however.

main.js (或之前的任何地方 router.activate()的叫法)我仍然守卫路线这需要身份验证:

In main.js (or anywhere before router.activate() is called) I still guard the route which requires authentication:

router.guardRoute = function (instance, instruction) {
    if (user.isAuthenticated()) {
        return true;
    } else {
        if (instance && typeof (instance.preventAnonymous) === "boolean") {
            if (instance.preventAnonymous) {
                return 'login/' + instruction.fragment;
            }
        }

        return true;
    }
};

shell.js

return {
    router: router,
    activate: function () {
        router.map([
            ...
            { route: 'login', title: '', moduleId: 'viewmodels/login', nav: true },
            { route: 'login/:redirect', title: '', moduleId: 'viewmodels/login', nav: true },
            ...
        ]).buildNavigationModel();
        return router.activate();
    },
    ...
}

的ViewModels / login.js

viewmodel = {
    ...,
    canActivate: function() {
        if (!user.isAuthenticated()) {
            return true;
        }
        return false;
    },

    activate: function(redirect) {
        viewmodel.redirect = redirect || "";
    },
    loginUser() {
        ...
        if (user.isAuthenticated()) {
            router.navigate(viewmodel.redirect);
        }
        ...
    },
    ...
}

限制

这种方法的一个轻微的负是页面片段的prescense在应用程序中的URL查询字符串一个成功的登录重定向到。如果你不喜欢在URL查询字符串本页面片段的prescence,本地存储可以很容易地而不是用于存储该值。在 router.guardRoute 人们可以简单的更换行

return 'login/' + instruction.fragment;

/* Check for local storage, cf. http://diveintohtml5.info/storage.html */
if ('localStorage' in window && window['localStorage'] !== null){
    localStorage.setItem("redirect", instruction.fragment);
    return 'login/';
} else {
    return 'login/' + instruction.fragment;
}

和我们的激活方法可以是这样的:

and our activate method could look like:

activate: function(redirect) {
    if ('localStorage' in window && window['localStorage'] !== null){
        viewmodel.redirect = localStorage.getItem("redirect");
    } else {
        viewmodel.redirect = redirect || "";
    }
},

这篇关于迪朗达尔登录页面重定向模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆