Angular16下基于Ngrx Effects实现登出撤销Token功能求助
Angular 16 结合 Google Identity 实现登出功能(NgRx版)
我正在用Angular 16搭配Google Identity与Google One Tap实现用户登录功能,当前开发登出模块,需要调用.NET后端接口撤销用户Token,计划通过分发Action触发登出流程,已完成以下实现:
已完成的实现部分
1. AuthApiService 中的 revokeToken 方法
接收email参数调用后端删除接口:
revokeToken(email: string) { const header = new HttpHeaders().set('Content-type', 'application/json'); return this.httpClient.delete(`api/v1/Auth/RevokeToken/` + email, { headers: header, withCredentials: true }); }
2. 定义 AuthActions 动作组
import { createActionGroup, emptyProps, props } from '@ngrx/store'; import { HttpErrorResponse } from '@angular/common/http'; export const AuthActions = createActionGroup({ source: 'Auth', events: { 'Logout Init': emptyProps(), 'Logout Success': emptyProps(), 'Logout Failed': props<{ error: HttpErrorResponse }>(), }, });
3. AuthState 及对应 Reducer 实现
import { createFeature, createReducer, on } from '@ngrx/store'; import { AuthActions } from './auth.actions'; import { LoadingState } from '../../shared/models/loading-state.model'; export interface AuthState { token: string; email: string; fullName: string; } export const initialState: AuthState = { token: '', email: '', fullName: '', }; export const authFeature = createFeature({ name: 'auth', reducer: createReducer( initialState, on(AuthActions.logoutInit, (state) => ({ ...state, ...LoadingState.loading(), })), on(AuthActions.logoutSuccess, (state) => ({ ...state, token: '', email: '', fullName: '', ...LoadingState.loaded(), })), on(AuthActions.logoutFailed, (state, { error }) => ({ ...state, ...LoadingState.failed(error), })), ) })
遇到的问题:NgRx Effects 无法正常工作
我编写的Effects代码无法实现预期逻辑,尝试代码如下:
revokeTokenAtLogout$ = createEffect(() => { return this.actions$.pipe( ofType(AuthActions.logoutInit), concatLatestFrom(() => this.store.select(selectEmail)), map(([action, email]) => { this.authApiService.revokeToken(email).pipe( AuthActions.logoutSuccess(), catchError(error => of(AuthActions.logoutFailed({error}))) ) }) ) })
预期实现逻辑
- 监听
logoutInit动作; - 从Store中获取当前用户的email;
- 将email传入
revokeToken方法调用后端接口; - 调用成功则触发
logoutSuccess并跳转至登录页; - 调用失败则触发
logoutFailed动作。
正确解决方案
经过调试,最终实现的正确Effects代码如下:
@Injectable() export class AuthEffects { constructor( private readonly actions$: Actions, private readonly store: Store, private readonly authApiService: AuthApiService, private router: Router, ) {} revokeTokenAtLogout$ = createEffect(() => { return this.actions$.pipe( ofType(AuthActions.logoutInit), concatLatestFrom(() => this.store.select(selectEmail)), switchMap(([, email]) => this.authApiService.revokeToken(email).pipe( map(() => AuthActions.logoutSuccess()), catchError(error => of(AuthActions.logoutFailed({ error }))) ), ), ); }); logoutNavigate$ = createEffect(() => { return this.actions$.pipe( ofType(AuthActions.logoutSuccess), tap(() => { this.router.navigate(['login']).then(() => window.location.reload()); }) ); }, { dispatch: false }) }
内容的提问来源于stack exchange,提问作者Chrizzar
相关产品推荐
相关产品推荐

