本文介绍了在页面刷新中:ngrx store dispatch issue with guard canactivate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我没有登录页面,这是 sso 调用

i don't have an login page , this is sso call

在应用程序组件中,我已经调度了一个动作来加载服务器端令牌调用并获取令牌,并根据用户角色我可以在路由中激活守卫.如果守卫激活返回true,我会去仪表板页面.

In the app component, I have dispatched an action to load the server-side token call and get the token and based on the user roles I can activate the guard in routing. if guard activates return true, I will go the dashboard page.

在dashboard页面中,我在浏览器URL中刷新,可以在登录动作效果之前激活执行,因此可以激活返回false并且页面显示为空白.

In the dashboard page, I have a refresh in the browser URL, can activate execute before the login action effects, therefore can activate return false and page displays blank.

仪表盘里有子路由,也有一些子链接,比如产品仪表板/产品,也有激活的守卫,但可以在登录调度动作影响成功调用之前激活返回false.

In the dashboard have child routes, there also have some child links like productsdashboard/products, there also have activated guard, but can activate return false before the login dispatch action effects success call.

有人能帮我做错什么吗?

Can anyone help me what I am doing wrong?

这里是路由,

  {
    path: '',
    component: HomeComponent,
    canActivate:[AuthGuard],
    children: [
      {
        path: 'product',
        loadChildren: () => productModule
      },
      {
        path: 'order',
        loadChildren: () => orderModule
      }
    ]
  },

这里是激活方法:在这里,我从效果调用中获得成功,同时从 app.component 分派动作:

here is activate method:here i get the success from effects call while dispatch an action from app.component:

  canActivate(): Observable<boolean> {
     return this.store.select(appState => appState.auth.isAuthenticated)
      .pipe(map(authUser => {

        if (!authUser) {
          return authUser;
        }
        return authUser;
      }))
    }

应用程序组件:

ngOnInit(){



   this.onSubmit();

}

onSubmit(): void {
  const payload = {
    email: '[email protected]',
    password: 'admin'
  };
  alert('dispatch an action');
  this.store.dispatch(new LogIn(payload));
}

问题只出现在页面刷新上.单击路由器链接时,逻辑工作正常.

the problem only in a page refresh. when clicking on the router link, the logic works fine.

我的初始状态:

export const initialState: State = {
  isAuthenticating:false,
  isAuthenticated: false,
  user: null,
  errorMessage: null
};

流程截图:

推荐答案

我可能有解决方案.

基本上你可以在你的初始状态设置一个属性来表明你正在初始化:

Basically you can set a property in your initial state to indicate that you're initializing:

export interface State {
  isAuthenticated: boolean;
  isInitializing: boolean;
}

const initialState: State = {
  isAuthenticated: false,
  isInitializing: true
}

并且当您发送登录或注销时,请确保在 reducer 中将 isInitializing 设置为 false:

And when you dispatch a login or logout, make sure to set isInitializing to false in the reducer:

const _authReducer = createReducer(
  initialState,

  on(AuthActions.setAuthenticated, (state, action) => ({
    ...state,
    isAuthenticated: true,
    isInitializing: false,
  })),

  on(AuthActions.setUnauthenticated, (state, action) => ({
    ...state,
    isAuthenticated: false,
    isInitializing: false,
  }))
);

在您的守卫中,您可以使用过滤器等待 isInitializing 设置为 false,然后再返回有关用户身份验证的信息:

In your guard, you can then use a filter to wait for isInitializing to be set to false, before returning information about the user authentication:

canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    console.log('Authguard running...');

    return this.store.select('auth').pipe(
      map(authState => authState.isInitializing),
      // tap((isInit) => {
      //   console.log('isInit: ' + isInit);
      // }),
      filter((isInit) => !isInit),
      switchMap(() => {
        return this.store.select('auth').pipe(
          map(authState => authState.isAuthenticated)
          // tap((isAuth) => {
          //   console.log('isAuth: ' + isAuth);
          // }),
          map((isAuth) => {
            if (isAuth) return isAuth;
            return this.router.createUrlTree(['/auth']);
          })
        );
      })
    );
  }

如果您想在控制台中监控这些值,您可以从 Tap 运算符中删除注释:)

You can remove the comments from the tap operators if you want to monitor these values in the console :)

我使用这个解决方案是为了能够在登录时重新加载特定的 url.如果您在未登录时尝试访问同一页面,您将被重定向到登录.

I'm using this solution to be able to reload on a specific url when logged in. If you try to visit that same page when not logged in you are redirected to the login.

这篇关于在页面刷新中:ngrx store dispatch issue with guard canactivate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 04:27