使用angular4和asp.net core 2 web api做个练习项目(四)
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的登陆页面.
登录成功后, 会跳转到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 系统设置
我们需要做一些全局的设置, 可以全局控制某些参数, 例如我们的余额是否可以输入.
建立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;
}
);
}
运行一下, 应该好用!
最后, 做一下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>
运行一下试试:
刷新, 查看添加和编辑页面,再刷新, 应该好用.
这个联系项目就到这了.
然后我要用asp.net core 2.0 web api 和 identity server 4 以及 angular 5 做一个项目了(angular 5正式版刚刚出来), 大约 300个页面......
也许之前还要做一个练习..请各位指教...
- 计算机程序的思维逻辑 (11) - 初识函数
- Android WebView 调试方法
- Python开发微信公众号后台(系列一)
- Consul最常用的命令和接口api
- webpack的Hot Module Replacement运行机制
- 如何使用Node.js编写命令工具——以vue-cli为例
- SpringBoot编写自定义的starter
- webpack3新特性简介
- Python机器学习算法入门之梯度下降法实现线性回归
- IronPython 2.0 beta 5
- node.js如何制作命令行工具(一)
- (28) 剖析包装类 (下) / 计算机程序的思维逻辑
- Linux进程监控工具Supervisor简易使用教程
- (29) 剖析String / 计算机程序的思维逻辑
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 基于TencentOS-tiny实现PM2.5传感器(攀藤PMSA003)数据解析思路及实现
- Centos7搭建SVN+Apache+iF.SVNAdmin实现web管理SVN
- 安卓最后一个大题复习
- 关于 Spring Ioc,看这一篇就够了!
- 第1次Spring源码学习之@Bean、@Configuration、xml、分析
- Spring 中的依赖注入(DI),你都知道多少?
- Docker配置1台Nginx+3台Tomcat做负载均衡
- Centos7.x+Docker部署RabbitMQ
- LeetCode(1)-找出数组中重复的数字
- LeetCode(面试题:二维数组中的查找)
- 面试题05-替换空格(LeeCode)
- 解决Mybatis当实体类中的属性名和表中的字段名不一致的问题
- 图书管理系统(一)项目框架结构搭建
- Mybatis中模糊查询like语句的使用方法
- win10暴力查看wifi密码