Как вернуться к просмотру после аутентификации в Аурелии
У меня есть мнение, что можно получить доступ по прямой ссылке из электронного письма.
Ex. Http: // MYSERVER:7747/#/ фото /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), а затем, когда это удается, я хочу, чтобы он вернулся на эту страницу, используя тот же urlParams.
У меня работает перенаправление на страницу входа, но вернуться к этому представлению оказывается сложно. Если я просто попробую использовать history.back()
проблема в том, что плагин аутентификации подтолкнул другой navigationInstruction (loginRedirect)
на историю, прежде чем я могу сделать что-нибудь. Если я просто пытаюсь жестко запрограммировать навигацию "вернуться назад дважды", я сталкиваюсь с проблемой, когда пользователь просто пытается войти в систему заново с главной страницы, а история отсутствует.
Похоже, это должно быть проще, чем есть, что я делаю не так?
2 ответа
Я заставил это работать, заменив 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, которая требует аутентификации.
Затем в моей учетной записи 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)
});
});
};
Надеюсь, это поможет кому-то!
Я не использовал плагин aurelia-authentication, но я могу помочь с базовой техникой, которую вы можете использовать, которая делает это очень простым. В вашем main.js
файл, установите в корне вашего приложения компонент "логин". В компоненте входа в систему, когда пользователь успешно прошел аутентификацию, задайте в корне вашего приложения компонент "оболочки" (или любой другой компонент, который вы выберете), который имеет представление маршрутизатора, и настройте маршрутизатор в своей модели представления. Как только это произойдет, маршрутизатор доставит пользователя к нужному компоненту на основе URL. Если пользователь выходит из системы, просто установите корень приложения обратно в компонент "login".
Вот небольшой поверхностный код, чтобы попытаться передать идею. Я предполагаю, что вы используете плагин 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);
}
.....