第一部分: http://www.cnblogs.com/cgzl/p/7755801.htmlcss
第二部分: http://www.cnblogs.com/cgzl/p/7763397.htmlhtml
第三部分: http://www.cnblogs.com/cgzl/p/7768147.htmlgit
後臺代碼: https://github.com/solenovex/asp.net-core-2.0-web-api-boilerplategithub
前臺代碼: https://github.com/solenovex/angular-4-client-panel-appweb
該系統的大部分頁面都應該是用戶登錄之後才能夠看見, 沒有登錄的話直接應該跳轉到登錄頁面.api
首先創建authguard:數組
ng g g guards/auth
代碼:angular2
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裏面引用並註冊:app
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.asp.net
別忘了在providers裏面註冊一下.
而後運行.
進入首頁 http://localhost:4200, 若是沒登錄, 那麼直接跳轉到authorization server的登錄頁面.
登陸成功後, 會跳轉到login-callback, 這裏有一個地方須要改一下(多是oidc-client的bug?):
ngOnInit() { this.authService.loginCallBack().subscribe( (user: User) => { if (user) { window.location.href = '/'; } } ); }
使用的是window.location.href='/', 若是使用angular的路由router.navigate跳轉的話會有問題.
登錄成功後跳轉到主頁.
因爲用戶註冊是在authorization server進行的, 因此把angular項目中的相關文件以及app.module裏面的調用刪除...
咱們須要作一些全局的設置, 能夠全局控制某些參數, 例如咱們的餘額是否能夠輸入.
創建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; }
而後運行一下:
發現點擊添加按鈕不起做用!!!!, 點擊明細也不起做用!!!!
後來發現, 是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; }); }
此次再試試, 就沒有問題了. 進入添加客戶頁面.
這個欄位的狀態會根據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; } ); }
運行一下, 應該好用!
須要改一下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>
運行一下試試:
刷新, 查看添加和編輯頁面,再刷新, 應該好用.
這個聯繫項目就到這了.
而後我要用asp.net core 2.0 web api 和 identity server 4 以及 angular 5 作一個項目了(angular 5正式版剛剛出來), 大約 300個頁面......
也許以前還要作一個練習..請各位指教...