angular - 在 Angular 8 中谷歌登录后如何重定向到上一页?
问题描述
在Angular8中谷歌登录后如何重定向到上一页?
我将当前 URL 保存在 localStorage 中,并在用户成功登录时使用它来导航。但它不是导航。
这是我的具有登录功能的 AuthService。
export class AuthService {
constructor(private afAuth: AngularFireAuth , private route: ActivatedRoute) {}
login() {
let returnUrl = this.route.snapshot.queryParamMap.get('returnUrl') || '/';
localStorage.setItem('returnUrl', returnUrl);
this.afAuth.auth.signInWithRedirect(new firebase.auth.GoogleAuthProvider());
}
}
这是我的 AuthGuardService
export class AuthGuardService implements CanActivate {
constructor(private auth: AuthService, public router: Router) {}
canActivate(route, state: RouterStateSnapshot) {
return this.auth.user$.pipe(map(user => {
if (user) { return false; }
this.router.navigate(['/login'], { queryParams : {returnUrl : state.url}});
return true;
}));
}
}
我正在使用 app.component.ts 导航到上一页。
export class AppComponent {
constructor(private auth: AuthService, router: Router) {
auth.user$.subscribe(user => {
if(user){
let returnUrl = localStorage.getItem('returnUrl');
router.navigate([returnUrl]);
}
});
}
}
这是我定义路由的 app.module.ts。
RouterModule.forRoot([
{ path: "", component: HomeComponent },
{ path: "check-out", component: CheckOutComponent, canActivate: [AuthGuardService] },
//...
])
我正在尝试从地址栏访问“结帐”页面。然后它会根据需要重定向到登录页面。(当用户未登录并且当用户尝试访问“签出”页面时,它会指向登录页面。)我的 URL 看起来像这样带有路由器参数。
http://localhost:4200/login?returnUrl=%2Fcheck-out
但登录后,它不会重定向回“结帐”页面。
用户登录后,我的 URI 如下所示
http://localhost:4200/login?returnUrl=%2Fcheck-out
它没有改变。但在 app.component.ts 我试图导航。
我找不到为什么在用户成功登录后没有导航回“结帐”页面。
解决方案
经过一整天的努力,这是我的解决方案。
为所有 url 操作创建一个服务:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class PreviousRouteService {
public setPreviousUrl(url: string) {
sessionStorage.setItem('previousUrl', url);
}
public getPreviousUrl() {
const previousUrl = sessionStorage.getItem('previousUrl');
return previousUrl;
}
public deletePreviousUrlKey() {
sessionStorage.removeItem('previousUrl');
}
}
回到你的警惕,如果他们没有登录,使用 state.url 来获取他们试图去的 url 并保存它:
// save the route
this.previousRouteService.setPreviousUrl(state.url);
像以前一样使用 signInWithRedirect :
this.afAuth.auth.signInWithRedirect(new firebase.auth.GoogleAuthProvider());
请注意,在 AF 6 中,额外的 .auth 被删除,所以看起来像:
this.afAuth.signInWithRedirect(new firebase.auth.GoogleAuthProvider());
signInWithRedirect 完成后,您将被送回您原来的地方。我无法从您的代码中完全看出,但我假设那是登录页面。所以在构造函数中的那个登录页面上(再次注意我已经为 AF 6 删除了额外的 .auth):
this.userSub = this.afAuth.authState.subscribe((user: firebase.User) => {
this.loggedIn = !!user;
this.user = user;
const previousRoute = this.previousRouteService.getPreviousUrl();
if (previousRoute) {
this.router.navigate([previousRoute]).then(() => {
// now reset so don't keep going back if coming to login page
// put some time otherwise it will delete it before above is finished
// even though that shouldn't be the case...
setTimeout(() => {
this.previousRouteService.deletePreviousUrlKey();
}, 8500);
});
}
});
我敢肯定,这不是最优雅的解决方案,但它确实有效。我真的不知道为什么在上一条路线导航到之后 setTimeout 是必要的 - 如果它还没有完成,那么有什么意义呢?或者可能与 authState 的工作和发射方式有关,不知道,但也许更好的工程师可以解释。无论如何,你去。
推荐阅读
- delphi - 如何使用 Virtual TreeView 模拟 TListView(vsIcon 模式)
- java - Spring Boot OAuth org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 null
- rust - 传递一个字符串切片,返回一个字符串切片。但谁拥有它?
- spring - 春季启动 - 自动装配失败
- xml - XamlWriter.Save(object) - 设置根和其他命名空间
- android - RecyclerView 中的多个查看器跳过项目
- html - 在windows操作系统下建站,在linux下变形。我如何解决它
- python - Flask - 可选路径参数
- javascript - 如何在不丢失 javascript 中的任何数据的情况下重新加载当前页面
- android - 将容器添加到小部件列表后立即对其进行动画处理(如它所显示的那样)