我正在尝试使用ngrx-store-localstorage将ngrx集成到我的身份验证过程中,以跨越浏览器会话存储令牌.
当我登录时,我可以在存储中看到令牌的价值
{"token":{"token":"e5cb6515-149c-44df-88d1-4ff16ff4169b","expiresIn":10385,"expiresAt":1512082478397},"authenticated":true,"error":false}
但是当我编辑一个页面并重新加载我的应用程序时
{"token":null,"authenticated":false,"error":false}
代码动作
import { Action } from '@ngrx/store'; import { AuthenticationTokenInterface } from '../authentication.interface'; export const LOGIN = 'LOGIN'; export const LOGIN_SUCCESS = 'LOGIN_SUCCESS'; export const LOGIN_Failed = 'LOGIN_Failed'; export const logoUT = 'logoUT'; export const SET_TOKEN = 'SET_TOKEN'; export class Login implements Action { readonly type = LOGIN; constructor(public payload: {username: 'string',password: 'string'}) {} } export class LoginSuccess implements Action { readonly type = LOGIN_SUCCESS; } export class LoginFailed implements Action { readonly type = LOGIN_Failed; } export class logout implements Action { readonly type = logoUT; } export class SetToken implements Action { readonly type = SET_TOKEN; constructor(public payload: AuthenticationTokenInterface) {} } export type AuthenticationActions = Login | LoginSuccess | LoginFailed | logout | SetToken;
@Injectable() export class AuthenticationEffects { @Effect() login$= this.actions$.ofType(AuthenticationActions.LOGIN) .pipe( mergeMap((action: AuthenticationActions.Login) => { return this.authenticationService.login(action.payload) .pipe( mergeMap((token:AuthenticationTokenInterface) => { this.router.navigate(['/main/dashboard']); return [ { type: AuthenticationActions.LOGIN_SUCCESS },{ type: AuthenticationActions.SET_TOKEN,payload: token } ] }),catchError(() => { return of({ type: AuthenticationActions.LOGIN_Failed }) }) ) }) ); @Effect({dispatch: false}) logout$= this.actions$.ofType(AuthenticationActions.logoUT) .pipe( switchMap(()=>{ this.router.navigate(['/logout']); return this.authenticationService.logout(); }) ); constructor( private actions$: Actions,private router: Router,private authenticationService: AuthenticationService ) {} }
减速机
export interface State { token: AuthenticationTokenInterface; authenticated: boolean; error: boolean; } const initialState: State = { token: null,authenticated: false,error: false }; export function authenticationReducer( state = initialState,action: AuthenticationActions.AuthenticationActions ):State { switch (action.type) { case (AuthenticationActions.LOGIN_SUCCESS): return { ...state,authenticated: true,}; case (AuthenticationActions.LOGIN_Failed): return { ...state,error: true }; case (AuthenticationActions.logoUT): return { ...state,token: null,authenticated: false }; case (AuthenticationActions.SET_TOKEN): return { ...state,token: action.payload }; default: return state; } }
减速器(App)
export interface AppState { authentication: fromAuthentication.State } export const reducers: ActionReducerMap<AppState> = { authentication: fromAuthentication.authenticationReducer };
应用模块
export function localStorageSyncReducer(reducer: ActionReducer<any>): ActionReducer<any> { return localStorageSync({keys: ['authentication']})(reducer); } const MetaReducers: Array<MetaReducer<any,any>> = [localStorageSyncReducer]; imports: [ StoreModule.forRoot( reducers,{MetaReducers} ),EffectsModule.forRoot([AuthenticationEffects]),]
您需要将rehydrate密钥添加到localStorageSync函数调用.
export function localStorageSyncReducer(reducer: ActionReducer<any>): ActionReducer<any> { return localStorageSync( {keys: ['authentication'],rehydrate: true})(reducer); }
有关详细信息,请参阅:https://github.com/btroncone/ngrx-store-localstorage/blob/master/README.md.