1

我有一个可以通过电子邮件中的直接链接访问的视图。

前任。 http://myServer:7747/#/pics/ClientId/YYYY-MM-DD

所以这是使用路由设置的:

{ route: ['/pics', '/pics/:clientId/:sessionDate', 'pics'], 
  name: 'pics', moduleId: './views/pics', nav: false, title: 'Pictures', 
  auth: true, activationStrategy: activationStrategy.invokeLifecycle 
},

因此,如果客户端单击此链接但未登录,我希望视图重定向到登录屏幕(我正在使用 aurelia-authentication 插件),然后当它成功时,我希望它使用相同的方法返回此页面网址参数。

我有重定向到登录页面的工作,但回到这个视图是困难的。如果我只是尝试使用history.back()问题是身份验证插件navigationInstruction (loginRedirect)在我做任何事情之前已经将另一个推送到历史记录中。如果我只是尝试对“返回两次”导航进行硬编码,那么当用户只是尝试从主页重新登录并且没有历史记录时,我会遇到问题。

似乎这应该比现在更容易,我做错了什么?

4

2 回答 2

0

我没有使用过 aurelia-authentication 插件,但我可以帮助您使用一种基本技术,使这变得非常容易。在您的main.js文件中,将应用程序的根目录设置为“登录”组件。在登录组件中,当用户成功通过身份验证后,将应用程序的根设置为具有路由器视图的“shell”组件(或您选择的任何组件),并在其视图模型中配置路由器。一旦发生这种情况,路由器将根据 url 将用户带到适当的组件。如果用户注销,只需将应用程序根设置回“登录”组件。

这里有一些粗略的代码来尝试传达这个想法。我假设您使用的是 SpoonX 插件,但这并不是必需的。只要您在用户进行身份验证时重置应用程序的根目录,它就可以工作。

在 main.js

.....
aurelia.start().then(() => aurelia.setRoot('login'));
.....

在 login.js 中

import {AuthService} from 'aurelia-authentication';
import {Aurelia, inject} from 'aurelia-framework';

@inject(AuthService, Aurelia)
export class Login {
    constructor(authService, aurelia) {
        this.authService = authService;
        this.aurelia = aurelia;
    }

    login(credentialsObject) {
        return this.authService.login(credentialsObject)
            .then(() => {
                this.authenticated = this.authService.authenticated;

                if (this.authenticated) {
                    this.aurelia.setRoot('shell');
                }
            });
    }

    .....
}

在 shell.html 中

.....
<router-view></router-view>
.....

在 shell.js 中

.....
configureRouter(config, router) {
    this.router = router;
    config.map(YOUR ROUTES HERE);
}
.....
于 2017-03-04T22:33:47.547 回答
0

我通过用我自己的替换插件的 authenticateStep 来实现这一点:

import { inject } from 'aurelia-dependency-injection';
import { Redirect } from 'aurelia-router';
import { AuthService } from "aurelia-authentication";
import { StateStore } from "./StateStore";

@inject(AuthService, StateStore)
export class SaveNavStep {
    authService: AuthService;
    commonState: StateStore;

    constructor(authService: AuthService, commonState: StateStore) {
        this.authService = authService;
        this.commonState = commonState;
    }

    run(routingContext, next) {
        const isLoggedIn = this.authService.authenticated;
        const loginRoute = this.authService.config.loginRoute;

        if (routingContext.getAllInstructions().some(route => route.config.auth === true)) {
            if (!isLoggedIn) {
                this.commonState.postLoginNavInstr = routingContext;
                return next.cancel(new Redirect(loginRoute));
            }
        } else if (isLoggedIn && routingContext.getAllInstructions().some(route => route.fragment === loginRoute)) {
            return next.cancel(new Redirect(this.authService.config.loginRedirect));
        }

        return next();
    }
}

我的和股票之间的唯一区别是我注入了一个“StateStore”对象,我在其中保存了需要身份验证的 NavigationInstruction。

然后在我的登录视图模型中,我注入这个相同的 StateStore(单例)对象并执行以下操作来登录:

login() {
    var redirectUri = '#/defaultRedirectUri';

    if (this.commonState.postLoginNavInstr) {
        redirectUri = this.routing.router.generate(this.commonState.postLoginNavInstr.config.name,
                            this.commonState.postLoginNavInstr.params,
                            { replace: true });
    }
    var credentials = {
        username: this.userName,
        password: this.password,
        grant_type: "password"
    };
    this.routing.auth.login(credentials,
        { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } },
        redirectUri
    ).catch(e => {
        this.dialogService.open({
            viewModel: InfoDialog,
            model: ExceptionHelpers.exceptionToString(e)
        });
    });
}; 

希望这对某人有帮助!

于 2017-03-06T17:19:56.320 回答