如何在刷新时获取身份验证保护中的用户和购物车数据?
How to get user and cart data in authentication guard on refresh?
我在 spartacus 店面使用 CheckoutAuthGuard
时遇到问题。当在结帐过程中的任何页面上按下浏览器刷新按钮时,由于缺少用户和购物车信息,守卫将我重定向到登录。
我曾经这样使用过CustomCheckoutAuthGuard
:
import { Injectable } from '@angular/core';
import {CanActivate, Router} from '@angular/router';
import {
ActiveCartService,
AuthRedirectService,
AuthService,
RoutingService,
User,
UserToken,
} from '@spartacus/core';
import { combineLatest, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import {CheckoutConfigService} from '@spartacus/storefront';
@Injectable()
export class CustomCheckoutAuthGuard implements CanActivate {
constructor(
protected routingService: RoutingService,
protected authService: AuthService,
protected authRedirectService: AuthRedirectService,
protected checkoutConfigService: CheckoutConfigService,
protected activeCartService: ActiveCartService,
private router: Router
) {}
canActivate(): Observable<boolean> {
return combineLatest([
this.authService.getUserToken(),
this.activeCartService.getAssignedUser(),
]).pipe(
map(([token, user]: [UserToken, User]) => {
if (!token.access_token) {
if (this.activeCartService.isGuestCart()) {
return Boolean(user);
}
if (this.checkoutConfigService.isGuestCheckout()) {
this.router.navigate(['checkout-login']);
} else {
this.routingService.go({ cxRoute: 'login' });
}
this.authRedirectService.reportAuthGuard();
}
return !!token.access_token;
})
);
}
}
它与斯巴达克斯的默认值 CheckoutAuthGuard
非常相似。我还为所有相关的结帐组件切换了这个守卫:
CheckoutOrchestrator: {
component: CheckoutOrchestratorComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard, CheckoutGuard],
},
CheckoutProgressMobileTop: {
component: CheckoutProgressMobileTopComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard],
},
CheckoutProgressMobileBottomComponent: {
component: CheckoutProgressMobileBottomComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard]
},
CheckoutProgress: {
component: CheckoutProgressComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard]
},
CheckoutDeliveryMode: {
component: DeliveryModeComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard, ShippingAddressSetGuard]
},
CheckoutPlaceOrder: {
component: PlaceOrderComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard]
},
CheckoutReviewOrder: {
component: ReviewSubmitComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard]
},
CheckoutShippingAddress: {
component: ShippingAddressComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard, CheckoutDetailsLoadedGuard]
}
但是在刷新时,来自 ActiveCartService
的用户是 undefined
也是 this.activeCartService.isGuestCart()
returns undefined
.
这一切都是为了访客结账,不幸的是我无法判断登录用户的行为是什么。这是因为我们使用 CDC,目前 CDC 有一个错误,任何刷新都重定向到主页,所以这个守卫被完全绕过。有关此问题的更多信息 here。
谁能给我建议最好在这里尝试什么?也许某些购物车状态需要与本地存储同步,或者 combineLatest
这里的 rxjs
函数是错误的?或者是其他东西?提前致谢!
这是一个已知问题,已在 Spartacus 3.0 版中修复。您可以查看我们打开的问题 here。目前没有计划将此更改移植到 3.0 之前的版本。
此问题是由于 运行 在购物车装载之前进行了警卫检查。
如果您在 3.0 之前需要此解决方案,我建议您使用它的自定义版本覆盖现成的 CheckoutAuthGuard
。您应该将 this.activeCartService.isStable()
值添加到 combineLatest
流,并在“购物车稳定”上添加 filter
。 Here你明白我的意思了。
以下是您应该如何提供自定义保护以替换默认保护:
(在 app.module.ts 或 AppModule 中导入的其他模块)
providers: [
...,
{
provide: CheckoutAuthGuard,
useClass: CustomCheckoutAuthGuard, //or whatever your guard class is named
}
]
我在 spartacus 店面使用 CheckoutAuthGuard
时遇到问题。当在结帐过程中的任何页面上按下浏览器刷新按钮时,由于缺少用户和购物车信息,守卫将我重定向到登录。
我曾经这样使用过CustomCheckoutAuthGuard
:
import { Injectable } from '@angular/core';
import {CanActivate, Router} from '@angular/router';
import {
ActiveCartService,
AuthRedirectService,
AuthService,
RoutingService,
User,
UserToken,
} from '@spartacus/core';
import { combineLatest, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import {CheckoutConfigService} from '@spartacus/storefront';
@Injectable()
export class CustomCheckoutAuthGuard implements CanActivate {
constructor(
protected routingService: RoutingService,
protected authService: AuthService,
protected authRedirectService: AuthRedirectService,
protected checkoutConfigService: CheckoutConfigService,
protected activeCartService: ActiveCartService,
private router: Router
) {}
canActivate(): Observable<boolean> {
return combineLatest([
this.authService.getUserToken(),
this.activeCartService.getAssignedUser(),
]).pipe(
map(([token, user]: [UserToken, User]) => {
if (!token.access_token) {
if (this.activeCartService.isGuestCart()) {
return Boolean(user);
}
if (this.checkoutConfigService.isGuestCheckout()) {
this.router.navigate(['checkout-login']);
} else {
this.routingService.go({ cxRoute: 'login' });
}
this.authRedirectService.reportAuthGuard();
}
return !!token.access_token;
})
);
}
}
它与斯巴达克斯的默认值 CheckoutAuthGuard
非常相似。我还为所有相关的结帐组件切换了这个守卫:
CheckoutOrchestrator: {
component: CheckoutOrchestratorComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard, CheckoutGuard],
},
CheckoutProgressMobileTop: {
component: CheckoutProgressMobileTopComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard],
},
CheckoutProgressMobileBottomComponent: {
component: CheckoutProgressMobileBottomComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard]
},
CheckoutProgress: {
component: CheckoutProgressComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard]
},
CheckoutDeliveryMode: {
component: DeliveryModeComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard, ShippingAddressSetGuard]
},
CheckoutPlaceOrder: {
component: PlaceOrderComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard]
},
CheckoutReviewOrder: {
component: ReviewSubmitComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard]
},
CheckoutShippingAddress: {
component: ShippingAddressComponent,
guards: [CustomCheckoutAuthGuard, CartNotEmptyGuard, CheckoutDetailsLoadedGuard]
}
但是在刷新时,来自 ActiveCartService
的用户是 undefined
也是 this.activeCartService.isGuestCart()
returns undefined
.
这一切都是为了访客结账,不幸的是我无法判断登录用户的行为是什么。这是因为我们使用 CDC,目前 CDC 有一个错误,任何刷新都重定向到主页,所以这个守卫被完全绕过。有关此问题的更多信息 here。
谁能给我建议最好在这里尝试什么?也许某些购物车状态需要与本地存储同步,或者 combineLatest
这里的 rxjs
函数是错误的?或者是其他东西?提前致谢!
这是一个已知问题,已在 Spartacus 3.0 版中修复。您可以查看我们打开的问题 here。目前没有计划将此更改移植到 3.0 之前的版本。
此问题是由于 运行 在购物车装载之前进行了警卫检查。
如果您在 3.0 之前需要此解决方案,我建议您使用它的自定义版本覆盖现成的 CheckoutAuthGuard
。您应该将 this.activeCartService.isStable()
值添加到 combineLatest
流,并在“购物车稳定”上添加 filter
。 Here你明白我的意思了。
以下是您应该如何提供自定义保护以替换默认保护:
(在 app.module.ts 或 AppModule 中导入的其他模块)
providers: [
...,
{
provide: CheckoutAuthGuard,
useClass: CustomCheckoutAuthGuard, //or whatever your guard class is named
}
]