Week 11 · Day 04 — 實作:用戶認證模組

學習目標

  • 建立 AuthService 呼叫登入/註冊 API
  • 用 NgRx 管理認證狀態與 token
  • 用路由守衛保護任務頁

重點

AuthService(呼叫 API)

@Injectable({ providedIn: 'root' })
export class AuthService {
  private api = 'https://api.example.com';

  constructor(private http: HttpClient) {}

  login(email: string, password: string): Observable<AuthResponse> {
    return this.http.post<AuthResponse>(`${this.api}/login`, { email, password });
  }

  register(name: string, email: string, password: string) {
    return this.http.post<AuthResponse>(`${this.api}/register`, { name, email, password });
  }
}

認證狀態(NgRx)

// actions
loginSuccess({ user, token });  logout();

// reducer state
{ user: User | null, token: string | null, loading: boolean }

// selector
selectIsAuthenticated, selectUser, selectToken

登入流程(Effect)

login$ = createEffect(() =>
  this.actions$.pipe(
    ofType(login),
    switchMap(({ email, password }) =>
      this.authService.login(email, password).pipe(
        map(res => {
          localStorage.setItem('token', res.token);   // 存 token
          return loginSuccess({ user: res.user, token: res.token });
        }),
        catchError(err => of(loginFailure({ error: err.message })))
      )
    )
  )
);

AuthGuard 保護任務頁

canActivate(): boolean {
  if (this.store.selectSnapshot(selectIsAuthenticated)) return true;
  this.router.navigate(['/auth/login']);
  return false;
}
→ 套到 /tasks 路由。

登出 清除 token + 清 state + 導回登入頁。

實作

  1. 建立 AuthService
  2. 建立認證 store(actions/reducer/effects/selectors)
  3. 建立 login / register 頁面表單
  4. 用 AuthGuard 保護 /tasks

作業

  • 建立登入/註冊 API 服務
  • 用 NgRx 管理認證狀態與 token
  • 用守衛保護任務頁