2017-03-04 140 views
1

我有一个可以通过电子邮件的直接链接访问的视图。如何在Aurelia的身份验证后返回查看

Ex。 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插件),然后当它成功时,我希望它使用相同的urlParams返回到此页面。

我有重定向到登录页面工作,但回到这个视图证明是困难的。如果我只是尝试使用history.back(),问题是身份验证插件已将另一个navigationInstruction (loginRedirect)推到历史记录上,然后我才能执行任何操作。如果我只是尝试硬编码“返回两次”导航,那么当用户仅尝试从主页面重新登录并且没有历史记录时,就会遇到问题。

看起来像这样应该比它容易,我做错了什么?

回答

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) 
     }); 
    }); 
}; 

希望这可以帮助别人!

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); 
} 
..... 
+0

嗨,杰夫,谢谢你的帮助!我之前发现了类似的解决方案,但是我遇到了菜单无法正确加载的问题(是的,我尝试了ServiceStack的各种解决方案来重置,禁用等...路由器),这也不能解决我之后的用例。因此,为了使用您的示例,我有一封电子邮件,该链接指向具有特定电子邮件特定urlParams的'shell'应用中的视图,但是当用户单击该链接并且未登录时,应该重定向用户以登录并然后在登录时他们应该返回到所有最初提交的urlParms的视图。 – Bitfiddler

相关问题