Anguar 7使用NGRX并将令牌保存在localStorage中

时间:2018-11-29 17:57:06

标签: angular ngrx ngrx-store ngrx-effects

在我的Angular应用程序中,我使用了NGRX存储,保存的用户令牌存在一些问题。 有时我会重新加载页面并丢失所有内容。

在app.component.ts中实现OnInit并在其中添加:

this.store.select('auth').subscribe(event => {
  if (event.token) {
    window.localStorage.setItem('token', JSON.stringify(event.token));
  }
});

if (window.localStorage.getItem('token')) {
  const token = JSON.parse(window.localStorage.getItem('token'));
  this.store.dispatch(new AuthActions.SetToken(token));
}

并创建了效果:

@Effect()
this.actions$.pipe(
    ofType<AuthActions.TrySignin> (
        AuthActions.AuthActionTypes.TRY_SIGNIN
    ),
        switchMap(action => {
            return this.httpClient.put('http://localhost:8080/api/signin', {
                username: action.payload.username,
                password: action.payload.password
            }, {
                    observe: 'body',
                    responseType: 'text'
                }).pipe(
                    map(
                        token => {
                            this.router.navigate(['/']);
                            return new AuthActions.SetToken(token);
                        }
                    ),
                    catchError(error => {
                        return of(new AuthActions.AuthFailed(error));
                    }
                    )
                );

        }
        )
);

对吗?

4 个答案:

答案 0 :(得分:1)

为什么不直接将令牌保存到本地存储中?

此方法的缺点是,您必须记住在出现令牌时订阅存储和保存令牌。 第二个坏事是,每当auth状态发出数据时,即使之前是正确的,您的订阅也会保存令牌。

获取令牌代码很不错。

答案 1 :(得分:0)

我建议您不要在组件内部执行此操作。 它们将变得更加难以测试,而且您最终可能在不同组件中使用相同的代码。

代替使用,您可以按照Maciej的建议在内部效果中进行操作,有关其他示例,请参见https://github.com/tomastrajan/angular-ngrx-material-starter/blob/master/src/app/examples/form/form.effects.ts#L20

但就我个人而言,我喜欢为此使用meta-reducer-请参见https://github.com/timdeschryver/ngrx-family-grocery-list/blob/master/src/app/groceries/reducers/groceries.reducer.ts#L165

例如:

export function persistStateReducer(_reducer: ActionReducer<State>) {
  const localStorageKey = '__auth';
  return (state: State | undefined, action: Action) => {
    if (state === undefined) {
      const persisted = localStorage.getItem(localStorageKey);
      return persisted ? JSON.parse(persisted) : _reducer(state, action);
    }

    const nextState = _reducer(state, action);
    localStorage.setItem(localStorageKey, JSON.stringify(nextState));
    return nextState;
  };
}

答案 2 :(得分:0)


shopt -s expand_aliases
alias php="/usr/local/bin/php-5.6"
./some-script.sh
unalias php # back to previous version

答案 3 :(得分:0)

默认情况下,刷新页面时,您的应用程序状态会重置。

您需要做的是,将“身份验证”状态保存到持久存储中,例如localstorage / sessionstorage。

并在启动时从本地存储/会话存储恢复状态。

我创建了一个库来轻松为您处理: https://github.com/larscom/ngrx-store-storagesync

  1. 运行:
  

npm install --save @ larscom / ngrx-store-storagesync

  1. 配置meta reducer

配置将类似于以下设置

wtf.hs:5:5: error:
    parse error (possibly incorrect indentation or mismatched brackets)
Failed, modules loaded: none.

就是这样,如果您重新加载页面,状态将从sessionStorage恢复(在这种情况下)