使用 Ngrx 从 Firebase 检查 Auth 状态
Check Auth state from Firebase with Ngrx
我正在尝试检查我的应用程序的身份验证状态,验证它是否有经过身份验证的用户。
我有一个 logged
为假的初始状态,当我尝试签入 CanActivate()
时,记录返回为假。
我检查了 Redux DevTools 并更改了 auth 状态,因此记录的值更改为 true。
我做错了什么?如何验证用户是否已使用 NGRX 进行身份验证?
guard.ts
constructor(
private _store: Store<fromAuth.AuthState>
) { }
canActivate(): Observable<boolean> {
return this.checkUserLogged(); // Return is always false
}
private checkUserLogged() {
return this._store.select(fromAuth.isLogged).pipe(take(1));
}
app.component.ts
import { Store } from '@ngrx/store';
import * as fromAuth from '@myapp/store/reducers/auth.reducer';
import * as authActions from '@myapp/store/actions/auth.actions';
constructor(
private _store: Store<fromAuth.AuthState>,
) {
this._store.dispatch(new authActions.GetUser());
auth.reducer.ts
export interface AuthState {
logged: boolean;
;
export const initialState: AuthState = {
logged: false,
};
export function authReducer(state = initialState, action: Action):
AuthState {
switch (action.type) {
case authActions.GET_USER:
return {
...state,
logged: false
};
case authActions.AUTHENTICATED:
return {
...state,
...action.payload,
loading: false,
logged: true,
};
// emitted ....
}
export const getAuthState = createFeatureSelector<AuthState>('auth');
export const isLogged = createSelector(
getAuthState, (state: AuthState) =>
state.logged);
auth.effects.ts
@Injectable({
providedIn: 'root'
})
export class AuthEffects {
constructor(
private _actions: Actions,
private _angularFireAuth: AngularFireAuth) { }
@Effect()
getUser$: Observable<Action> = this._actions.pipe(
ofType(authActions.GET_USER),
switchMap(() => this._angularFireAuth.authState),
switchMap(user => forkJoin([
from(user.getIdTokenResult(true)), of(user)])
.pipe(map(([token, user]) => {
if (user) {
const authState = {
firestoreCollection: token.claims.firestoreCollection,
user: {
admin: token.claims.admin,
uid: user.uid,
displayName: user.displayName
}
};
// You are returning this action
// Soon after logged in should be true.
return new authActions.Authenticated(authState);
} else {
return new authActions.NotAuthenticated();
}
}))),
catchError((error) => of(new authActions.AuthError(error)))
)
}
因为你已经在 reducer 中记录了状态,你可以编写 index.ts 文件来像这样从商店中获取数据
import * as fromRoot from '@core/store/reducers/index';
import { AuthState } from './reducers/auth.reducer';
import { createFeatureSelector, createSelector } from '@ngrx/store';
export interface State extends fromRoot.State {
auth: AuthState;
}
export const selectAuthState = createFeatureSelector<AuthState>('authModule');
export const selectIsLoginState = createSelector(
selectAuthState,
state => state.logged
);
基本上您需要创建选择器以使用 createFeatureSelector、createSelector 从商店获取数据
我正在尝试检查我的应用程序的身份验证状态,验证它是否有经过身份验证的用户。
我有一个 logged
为假的初始状态,当我尝试签入 CanActivate()
时,记录返回为假。
我检查了 Redux DevTools 并更改了 auth 状态,因此记录的值更改为 true。
我做错了什么?如何验证用户是否已使用 NGRX 进行身份验证?
guard.ts
constructor(
private _store: Store<fromAuth.AuthState>
) { }
canActivate(): Observable<boolean> {
return this.checkUserLogged(); // Return is always false
}
private checkUserLogged() {
return this._store.select(fromAuth.isLogged).pipe(take(1));
}
app.component.ts
import { Store } from '@ngrx/store';
import * as fromAuth from '@myapp/store/reducers/auth.reducer';
import * as authActions from '@myapp/store/actions/auth.actions';
constructor(
private _store: Store<fromAuth.AuthState>,
) {
this._store.dispatch(new authActions.GetUser());
auth.reducer.ts
export interface AuthState {
logged: boolean;
;
export const initialState: AuthState = {
logged: false,
};
export function authReducer(state = initialState, action: Action):
AuthState {
switch (action.type) {
case authActions.GET_USER:
return {
...state,
logged: false
};
case authActions.AUTHENTICATED:
return {
...state,
...action.payload,
loading: false,
logged: true,
};
// emitted ....
}
export const getAuthState = createFeatureSelector<AuthState>('auth');
export const isLogged = createSelector(
getAuthState, (state: AuthState) =>
state.logged);
auth.effects.ts
@Injectable({
providedIn: 'root'
})
export class AuthEffects {
constructor(
private _actions: Actions,
private _angularFireAuth: AngularFireAuth) { }
@Effect()
getUser$: Observable<Action> = this._actions.pipe(
ofType(authActions.GET_USER),
switchMap(() => this._angularFireAuth.authState),
switchMap(user => forkJoin([
from(user.getIdTokenResult(true)), of(user)])
.pipe(map(([token, user]) => {
if (user) {
const authState = {
firestoreCollection: token.claims.firestoreCollection,
user: {
admin: token.claims.admin,
uid: user.uid,
displayName: user.displayName
}
};
// You are returning this action
// Soon after logged in should be true.
return new authActions.Authenticated(authState);
} else {
return new authActions.NotAuthenticated();
}
}))),
catchError((error) => of(new authActions.AuthError(error)))
)
}
因为你已经在 reducer 中记录了状态,你可以编写 index.ts 文件来像这样从商店中获取数据
import * as fromRoot from '@core/store/reducers/index';
import { AuthState } from './reducers/auth.reducer';
import { createFeatureSelector, createSelector } from '@ngrx/store';
export interface State extends fromRoot.State {
auth: AuthState;
}
export const selectAuthState = createFeatureSelector<AuthState>('authModule');
export const selectIsLoginState = createSelector(
selectAuthState,
state => state.logged
);
基本上您需要创建选择器以使用 createFeatureSelector、createSelector 从商店获取数据