天天看點

使用angular4和asp.net core 2 web api做個練習項目(四)Auth Guard做一些清理工作:Settings 系統設定最後, 做一下Settings頁面

第一部分:  http://www.cnblogs.com/cgzl/p/7755801.html 第二部分:  http://www.cnblogs.com/cgzl/p/7763397.html 第三部分:  http://www.cnblogs.com/cgzl/p/7768147.html 背景代碼:  https://github.com/solenovex/asp.net-core-2.0-web-api-boilerplate 前台代碼:  https://github.com/solenovex/angular-4-client-panel-app

Auth Guard

該系統的大部分頁面都應該是使用者登陸以後才可以看見, 沒有登陸的話直接應該跳轉到登陸頁面.

首先建立authguard:

ng g g guards/auth      

代碼:

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { User } from 'oidc-client';
import { AuthService } from '../services/auth.service';

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(
    private router: Router,
    private authService: AuthService
  ) { }

  canActivate(): Observable<boolean> {
    return this.authService.loginStatusChanged.map((user: User) => {
      if (user) {
        return true;
      }
      this.authService.login();
      return false;
    });
  }
}      

然後在app.module.ts裡面引用并注冊:

import { AuthGuard } from './guards/auth.guard';

const appRoutes: Routes = [
  { path: '', component: DashboardComponent, canActivate: [AuthGuard] },
  { path: 'login-callback', component: LoginCallbackComponent },
  { path: 'register', component: RegisterComponent },
  { path: 'add-client', component: AddClientComponent, canActivate: [AuthGuard] },
  { path: 'client/:id', component: ClientDetailsComponent, canActivate: [AuthGuard] },
  { path: 'edit-client/:id', component: EditClientComponent, canActivate: [AuthGuard] }
];

  providers: [
    ClientService,
    AuthService,
    AuthGuard
  ],      

需要權限控制的路由需要加上 canActivate屬性, 它的值是一個數組可以使用多個guards.

别忘了在providers裡面注冊一下.

然後運作.

進入首頁 http://localhost:4200, 如果沒登陸, 那麼直接跳轉到authorization server的登陸頁面.

使用angular4和asp.net core 2 web api做個練習項目(四)Auth Guard做一些清理工作:Settings 系統設定最後, 做一下Settings頁面

登入成功後, 會跳轉到login-callback, 這裡有一個地方需要改一下(可能是oidc-client的bug?):

ngOnInit() {
    this.authService.loginCallBack().subscribe(
      (user: User) => {
        if (user) {
          window.location.href = '/';
        }
      }
    );
  }      

使用的是window.location.href='/', 如果使用angular的路由router.navigate跳轉的話會有問題.

使用angular4和asp.net core 2 web api做個練習項目(四)Auth Guard做一些清理工作:Settings 系統設定最後, 做一下Settings頁面

登陸成功後跳轉到首頁.

做一些清理工作:

由于使用者注冊是在authorization server進行的, 是以把angular項目中的相關檔案以及app.module裡面的調用删除...

Settings 系統設定

我們需要做一些全局的設定, 可以全局控制某些參數, 例如我們的餘額是否可以輸入.

建立settings service:

ng g s services/settings      

建立settings model:

ng g interface models/Settings      

生成的檔案名首字母是小寫的, 首字母還是改成大寫的吧...

Settings.ts:

export interface Settings {
  disableBalanceOnAdd?: boolean;
  disableBalanceOnEdit?: boolean;
}      

settings.service.ts:

import { Injectable } from '@angular/core';
import { Settings } from '../models/Settings';

@Injectable()
export class SettingsService {

  private _settings: Settings = {
    disableBalanceOnAdd: false,
    disableBalanceOnEdit: false
  };

  constructor() { }

  get settings() {
    return this._settings;
  }
}      

然後再app.module.ts裡面注冊:

import { SettingsService } from './services/settings.service';
providers: [

    ClientService,
    AuthService,
    SettingsService,
    AuthGuard
  ]      

然後我們使用settings service.

在add-client.component.ts裡面:

import { SettingsService } from '../../services/settings.service';

public disableBalanceOnAdd = false;

  constructor(
    public flashMessagesService: FlashMessagesService,
    public router: Router,
    public clientService: ClientService,
    public settingsService: SettingsService
  ) { }

  ngOnInit() {
    this.disableBalanceOnAdd = this.settingsService.settings.disableBalanceOnAdd;
  }      

然後運作一下:

使用angular4和asp.net core 2 web api做個練習項目(四)Auth Guard做一些清理工作:Settings 系統設定最後, 做一下Settings頁面

發現點選添加按鈕不起作用!!!!, 點選明細也不起作用!!!!

後來發現, 是auth service和auth guard裡面寫錯了, 先修改auth service:

tryGetUser() {
    return Observable.fromPromise(this.manager.getUser());
  }      

把這個方法改成public的.

然後修改: auth guard:

canActivate(): Observable<boolean> {
    return this.authService.tryGetUser().map((user: User) => {
      if (user) {
        return true;
      }
      this.authService.login();
      return false;
    });
  }      

這次再試試, 就沒有問題了. 進入添加客戶頁面.

使用angular4和asp.net core 2 web api做個練習項目(四)Auth Guard做一些清理工作:Settings 系統設定最後, 做一下Settings頁面

這個欄位的狀态會根據settings裡面的設定而變化.

同樣在edit-client裡面修改一下:

import { SettingsService } from '../../services/settings.service';

disableBalanceOnEdit = false;

  constructor(
    public clientService: ClientService,
    public router: Router,
    public route: ActivatedRoute,
    public flashMessagesService: FlashMessagesService,
    public settingsService: SettingsService
  ) { }

  ngOnInit() {
    this.disableBalanceOnEdit = this.settingsService.settings.disableBalanceOnEdit;
    // 擷取ID
    this.id = this.route.snapshot.params['id'];
    // 擷取Client
    this.clientService.getOne(+this.id).subscribe(
      client => {
        this.client = client;
      }
    );
  }      

運作一下, 應該好用!

最後, 做一下Settings頁面

需要改一下setting.serviec, 将使用localstorage來存儲settings:

import { Injectable } from '@angular/core';
import { Settings } from '../models/Settings';

@Injectable()
export class SettingsService {

  private _settings: Settings = {
    disableBalanceOnAdd: true,
    disableBalanceOnEdit: false
  };

  constructor() {
    if (localStorage.getItem('settings')) {
      this._settings = JSON.parse(localStorage.getItem('settings'));
    }
  }

  get settings() {
    return this._settings;
  }

  set settings(value: Settings) {
    this._settings = value;
    localStorage.setItem('settings', JSON.stringify(this._settings));
  }
}      

然後打開settings.component.ts:

import { Component, OnInit } from '@angular/core';
import { SettingsService } from '../../services/settings.service';
import { Router } from '@angular/router';
import { FlashMessagesService } from 'angular2-flash-messages';
import { Settings } from '../../models/Settings';

@Component({
  selector: 'app-settings',
  templateUrl: './settings.component.html',
  styleUrls: ['./settings.component.css']
})
export class SettingsComponent implements OnInit {

  settings: Settings;

  constructor(
    private settingsService: SettingsService,
    private flashMessagesService: FlashMessagesService,
    private router: Router
  ) { }

  ngOnInit() {
    this.settings = this.settingsService.settings;
  }

  onSubmit() {
    this.settingsService.settings = this.settings;
    this.flashMessagesService.show('Settings 儲存了', { cssClass: 'alert-success', timeout: 4000 });
  }

}      

這個很簡單.

然後是html:

<div class="row">
  <div class="col-md-6">
    <a routerLink="/" class="btn btn-link">
      <i class="fa fa-arrow-circle-o-left"></i> 回到Dashboard</a>
  </div>
  <div class="col-md-6">

  </div>
</div>

<div class="card">
  <div class="card-header">
    <h3>編輯 Settings</h3>
  </div>
  <div class="card-body">
    <form (submit)="onSubmit()">
      <div class="form-group">
        <label for="disableBalanceOnAdd">Disable Blance on Add</label>
        <input type="checkbox" id="disableBalanceOnAdd" name="disableBalanceOnAdd" [(ngModel)]="settings.disableBalanceOnAdd">
      </div>
      <div class="form-group">
        <label for="disableBalanceOnEdit">Disable Blance on Edit</label>
        <input type="checkbox" id="disableBalanceOnEdit" name="disableBalanceOnEdit" [(ngModel)]="settings.disableBalanceOnEdit">
      </div>
      <input type="submit" class="btn btn-primary btn-block" value="Submit">
    </form>
  </div>
</div>      

别忘了在app.module裡面添加路由:

const appRoutes: Routes = [
  { path: '', component: DashboardComponent, canActivate: [AuthGuard] },
  { path: 'login-callback', component: LoginCallbackComponent },
  { path: 'add-client', component: AddClientComponent, canActivate: [AuthGuard] },
  { path: 'client/:id', component: ClientDetailsComponent, canActivate: [AuthGuard] },
  { path: 'edit-client/:id', component: EditClientComponent, canActivate: [AuthGuard] },
  { path: 'settings', component: SettingsComponent, canActivate: [AuthGuard] },
  { path: '**', component: PageNotFoundComponent }
];      

順便把page Not found的路由也加上, 使用 ** wildcard.

最後在navbar.html 添加上連結按鈕:

<li *ngIf="isLoggedIn" class="nav-item">
          <a class="nav-link" href="#" routerLink="/settings">Settings </a>
        </li>      

運作一下試試:

使用angular4和asp.net core 2 web api做個練習項目(四)Auth Guard做一些清理工作:Settings 系統設定最後, 做一下Settings頁面

重新整理, 檢視添加和編輯頁面,再重新整理, 應該好用.

這個聯系項目就到這了.

然後我要用asp.net core 2.0 web api 和 identity server 4 以及 angular 5 做一個項目了(angular 5正式版剛剛出來), 大約 300個頁面......

也許之前還要做一個練習..請各位指教...

下面是我的關于ASP.NET Core Web API相關技術的公衆号--草根專欄:

使用angular4和asp.net core 2 web api做個練習項目(四)Auth Guard做一些清理工作:Settings 系統設定最後, 做一下Settings頁面

繼續閱讀