刷新页面时我丢失了有关用户的信息? Angular 2+ NgRx存储

我需要发布用户信息,但是我丢失了刷新信息。如何设置 isAuthenticated变量,我们在刷新时不会失去价值吗? 也许您无需查看大部分代码,只是告诉我如何立即修复它 您需要的一部分我的代码:

组件:

  getState: Observable<any>;
  isAuthenticated: false;
  user = null;
  errorMessage = null;
  globalisAuthenticated = null;
  constructor(public dialog: MatDialog,private store: Store<AppState>) {
    this.getState = this.store.select(selectAuthState);
   }
  ngOnInit() {
    this.getState.subscribe((state) => {
      this.isAuthenticated = state.isAuthenticated;
      this.user = state.user;
      this.errorMessage = state.errorMessage;
      // console.log("is",this.isAuthenticated)
      localStorage.setItem("isAuthenticated",state.isAuthenticated);
    });

减速器:

export interface State {
  // is a user authenticated?
  isAuthenticated: boolean;
  // if authenticated,there should be a user object
  user: User | null;
  // error message
  errorMessage: string | null;
}

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

    export function reducer(state = initialState,action: All): State {
      switch (action.type) {
        case AuthactionTypes.LOGIN_SUCCESS: {
          return {
            ...state,isAuthenticated: true,user: {
              token: action.payload.token,email: action.payload.email
            },errorMessage: null
          };
        }
        case AuthactionTypes.LOGIN_FAILURE: {
          return {
            ...state,errorMessage: 'Incorrect email and/or password.'
          };
        }
        default: {
          return state;
        }
      }
    }

效果:

  @Effect()
LogIn: Observable<any> = this.actions
  .ofType(AuthactionTypes.LOGIN)
  .map((action: LogIn) => action.payload)
  .switchMap(payload => {
    return this.authService.logIn(payload.email,payload.password)
      .map((user) => {
        console.log(user);
        return new LogInSuccess({token: user.token,email: payload.email});
      })
      .catch((error) => {
        console.log(error);
        return Observable.of(new LogInFailure({ error: error }));
      });
  });

  @Effect({ dispatch: false })
LogInSuccess: Observable<any> = this.actions.pipe(
  ofType(AuthactionTypes.LOGIN_SUCCESS),tap((user) => {
    console.log("User",user);
    localStorage.setItem('token',user.payload.token);
    this.snackBar.open("Uspesno ste ste prijavili.",null,{
      duration: 5000,verticalPosition: 'bottom',horizontalPosition: 'right'
   });
  })
);

状态:

export interface AppState {
  authState: auth.State;
}

export const reducers = {
  auth: auth.reducer
};

export const selectAuthState = createFeatureSelector<AppState>('auth');

您能告诉我一种避免刷新时丢失数据的方法吗? 如果您需要更多信息,请问我。 现在一切正常。但是当我刷新时,我丢失了所有东西,但令牌在本地存储中。

UPDATE UPDATE UPDATE 我被添加了,但再次没有工作

  import { StoreModule,actionReducerMap,actionReducer,MetaReducer } from '@ngrx/store';
  import { localStorageSync } from 'ngrx-store-localstorage';
  import { reducers } from './reducers';


  // const reducers: actionReducerMap<IState> = {todos,visibilityFilter};

  export function localStorageSyncReducer(reducer: actionReducer<any>): actionReducer<any> {
    return localStorageSync({keys: ['todos']})(reducer);
  }
  const metaReducers: Array<MetaReducer<any,any>> = [localStorageSyncReducer];
fengzi3688 回答:刷新页面时我丢失了有关用户的信息? Angular 2+ NgRx存储

在刷新时丢失状态是正常的。您将需要自己保持状态或使用诸如https://www.npmjs.com/package/ngrx-store-localstorage之类的库。

,

您可以将该值保存为浏览器的localStorage:

localStorage.setItem("auth",JSON.stringify(this.isAuthentificated));

然后,当您访问应用程序时,获取值。

this.isAuthentificated = JSON.parse(localStorage.getItem("auth"));

但是,注销时,需要在localStorage上将值设置为false或删除密钥。 (我更喜欢第一个)

1)localStorage.removeItem("auth");

2)localStorage.setItem("auth",false);

,

尝试一下

  export function localStorageSyncReducer(reducer: ActionReducer<any>): ActionReducer<any> {
     return localStorageSync( {keys: ['auth'],rehydrate: true})(reducer);
  }
,

这是您对NgRx的期望。每次刷新浏览器时,您将需要重新获取用户。有多种方法可以做到这一点。我使用JWT身份验证,因此状态更新过程如下所示:

  1. 用户通过输入用户名和密码登录
  2. Angular成功验证了用户身份,并将发出的JWT保存到localStorage
  3. 用户刷新页面,这导致状态丢失。这不是问题,因为在组件的ngOnInit()挂钩中,您的代码应检查JWT令牌。如果在本地存储中找不到JWT,它将立即将身份验证状态设置为“已注销”。如果确实找到了JWT令牌,它将调度一个新动作,我们将其称为GET_USER
  4. GET_USER操作将具有单一效果。此效果将向您的/api/user路由发送API GET请求。

在这一点上,您可能想知道两件事。首先,您可能想知道GET请求的目的是什么?好吧,GET请求不会立即起作用。显然,您将需要某种HTTP标头与GET请求一起发送,以便后端可以确定您要获取的用户。为此,您可以设置一个HttpInterceptor。该拦截器将拦截每个传出的HTTP请求,并附加存储在localStorage中的JWT令牌。

其次,您可能想知道后端如何使用JWT令牌在数据库中查找用户。后端/api/user路由将执行以下操作:

  1. 从HTTP Authorization标头(由Angular HttpInterceptor填充)中获取JWT令牌
  2. 使用jsonwebtoken之类的库来验证JWT
  3. 如果JWT有效,则jsonwebtoken库将对其进行解码。颁发令牌时,您应该已经将用户ID保存在JWT有效负载的sub属性上。现在,您可以使用该sub属性从数据库中检索用户。
  4. 返回检索到的用户

好的,所以我们可以返回到原始流程。请记住,所有这些都是由GET_USER操作引起的,该操作的效果是向/api/user

发出了GET请求
  1. 此时,您应该可以访问效果中的用户对象。现在,您将返回另一个动作,例如GET_USER_SUCCESS,并将用户对象作为参数传递给该动作。
  2. GET_USER_SUCCESS将具有一个简化程序,该简化程序将设置应用程序的身份验证状态。例如,您可以将属性isAuthenticated设置为true,并将属性user设置为附加到GET_USER_SUCCESS动作有效负载的用户对象。

总而言之,NgRx在每次刷新时都清除状态这一事实是设计使然。在页面加载上填充用户当然不是一个简单的过程,但是一旦实现,您将拥有可预测的用户身份验证流程。

本文链接:https://www.f2er.com/3045790.html

大家都在问