如何在Aurelia中进行身份验证后返回视图
我有一个可以通过电子邮件直接链接访问的视图 前。 因此,这是使用路由设置的:如何在Aurelia中进行身份验证后返回视图,aurelia,aurelia-auth,Aurelia,Aurelia Auth,我有一个可以通过电子邮件直接链接访问的视图 前。 因此,这是使用路由设置的: { route: ['/pics', '/pics/:clientId/:sessionDate', 'pics'], name: 'pics', moduleId: './views/pics', nav: false, title: 'Pictures', auth: true, activationStrategy: activationStrategy.invokeLifecycle }, 因
{ route: ['/pics', '/pics/:clientId/:sessionDate', 'pics'],
name: 'pics', moduleId: './views/pics', nav: false, title: 'Pictures',
auth: true, activationStrategy: activationStrategy.invokeLifecycle
},
因此,如果客户端单击此链接但未登录,我希望视图重定向到登录屏幕(我使用的是aurelia身份验证插件),然后在成功时,我希望它使用相同的urlParams返回此页面
我可以重定向到登录页面,但是返回到这个视图是很困难的。如果我只是尝试使用history.back()
的话,问题是身份验证插件在我做任何事情之前已经将另一个navigationInstruction(LoginDirect)
推到了历史记录上。如果我只是尝试硬编码一个“返回两次”导航,那么当用户只是尝试从主页新鲜登录而没有历史记录时,我就会遇到问题
看起来这应该比实际情况更简单,我做错了什么?我没有使用aurelia身份验证插件,但我可以帮助您使用一种基本技术,让这变得非常简单。在
main.js
文件中,将应用程序的根目录设置为“登录”组件。在登录组件中,当用户成功通过身份验证后,将应用程序的根目录设置为具有路由器视图的“shell”组件(或您选择的任何组件),并在其视图模型中配置路由器。一旦发生这种情况,路由器将根据url将用户带到适当的组件。如果用户注销,只需将应用程序根设置回“登录”组件
这里有一些粗略的代码试图传达这个想法。我假设您使用的是Sponx插件,但这并不是必须的。只要在用户进行身份验证时重置应用程序的根目录,它就会工作
在main.js中
.....
aurelia.start().then(() => aurelia.setRoot('login'));
.....
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');
}
});
}
.....
}
.....
configureRouter(config, router) {
this.router = router;
config.map(YOUR ROUTES HERE);
}
.....
登录到login.js中
.....
aurelia.start().then(() => aurelia.setRoot('login'));
.....
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');
}
});
}
.....
}
.....
configureRouter(config, router) {
this.router = router;
config.map(YOUR ROUTES HERE);
}
.....
在shell.html中
.....
<router-view></router-view>
.....
我还没有使用aurelia认证插件,但我可以帮助您使用一种基本技术,使之非常简单。在
main.js
文件中,将应用程序的根目录设置为“登录”组件。在登录组件中,当用户成功通过身份验证后,将应用程序的根目录设置为具有路由器视图的“shell”组件(或您选择的任何组件),并在其视图模型中配置路由器。一旦发生这种情况,路由器将根据url将用户带到适当的组件。如果用户注销,只需将应用程序根设置回“登录”组件
这里有一些粗略的代码试图传达这个想法。我假设您使用的是Sponx插件,但这并不是必须的。只要在用户进行身份验证时重置应用程序的根目录,它就会工作
在main.js中
.....
aurelia.start().then(() => aurelia.setRoot('login'));
.....
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');
}
});
}
.....
}
.....
configureRouter(config, router) {
this.router = router;
config.map(YOUR ROUTES HERE);
}
.....
登录到login.js中
.....
aurelia.start().then(() => aurelia.setRoot('login'));
.....
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');
}
});
}
.....
}
.....
configureRouter(config, router) {
this.router = router;
config.map(YOUR ROUTES HERE);
}
.....
在shell.html中
.....
<router-view></router-view>
.....
我用自己的AuthenticateTest替换了插件的AuthenticateTest,实现了这一点:
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”对象,在其中保存需要身份验证的导航指令
然后在我的登录viewModel中,我注入了这个相同的StateStore(singleton)对象,并执行如下操作来登录:
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)
});
});
};
希望这对别人有帮助 我用我自己的AuthenticateTest替换插件的AuthenticateTest来实现这一点:
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”对象,在其中保存需要身份验证的导航指令
然后在我的登录viewModel中,我注入了这个相同的StateStore(singleton)对象,并执行如下操作来登录:
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)
});
});
};
希望这对别人有帮助 嗨,杰夫,谢谢你的帮助!我以前也找到过类似的解决方案,但我遇到了菜单无法正确重新加载的问题(是的,我尝试了从ServiceStack到重置、停用等各种解决方案……路由器),这也不能解决我所追求的用例。因此,以您的示例为例,我有一封电子邮件,其中有一个指向“shell”应用程序中某个视图的链接,该视图具有特定于电子邮件的urlParms,但当用户单击该链接但未登录时,应将用户重定向至登录,然后在登录时,他们应返回该视图,并显示最初提交的所有urlParms。嗨,杰夫,感谢您的帮助!我以前也找到过类似的解决方案,但我遇到了菜单无法正确重新加载的问题(是的,我尝试了从ServiceStack到重置、停用等各种解决方案……路由器),这也不能解决我所追求的用例。因此,以您的示例为例,我有一封电子邮件,其中链接到“shell”应用程序中的一个视图,该视图具有特定于电子邮件的urlParms,但当用户单击该链接但未登录时,应重定向用户以登录,然后在登录时,他们应返回该视图,并显示最初提交的所有urlParms。