第一部分: http://www.cnblogs.com/cgzl/p/7755801.html

第二部分: http://www.cnblogs.com/cgzl/p/7763397.html

后台代码: https://github.com/solenovex/asp.net-core-2.0-web-api-boilerplate

前台代码: https://github.com/solenovex/angular-4-client-panel-app

下面将开发登陆和授权的部分, 这里要用到identity server 4.

在VS解决方案中设置多个项目同时启动:

AspNetIdentityAuthorizationServer就是authorization server. 它的地址是 http://localhost:5000

CoreApi.Web作为api, 都已经配置好了.它的地址是 http://localhost:5001

Login 登陆

由于我们使用的是Identity Server 4的登录页面, 所以angular项目里面无需登录页面, 把login相关的文件删除...........

登陆需要使用到oidc-client.js所以通过npm安装:

npm install --save oidc-client

Auth Service

需要登陆服务 auth.service:

ng g s services/auth

打开auth.services.ts:

import { Injectable, OnInit, EventEmitter } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { User, UserManager, Log } from 'oidc-client';
import 'rxjs/add/observable/fromPromise'; const config: any = {
authority: 'http://localhost:5000',
client_id: 'corejs',
redirect_uri: 'http://localhost:4200/login-callback',
response_type: 'id_token token',
scope: 'openid profile coreapi',
post_logout_redirect_uri: 'http://localhost:4200/index.html',
};
Log.logger = console;
Log.level = Log.DEBUG; @Injectable()
export class AuthService implements OnInit { private manager: UserManager = new UserManager(config);
public loginStatusChanged: EventEmitter<User>; constructor() {
this.loginStatusChanged = new EventEmitter();
} ngOnInit() { } login() {
this.manager.signinRedirect();
} loginCallBack() {
return Observable.create(observer => {
Observable.fromPromise(this.manager.signinRedirectCallback())
.subscribe(() => {
this.tryGetUser().subscribe((user: User) => {
this.loginStatusChanged.emit(user);
observer.next(user);
observer.complete();
}, e => {
observer.error(e);
});
});
});
} checkUser() {
this.tryGetUser().subscribe((user: User) => {
this.loginStatusChanged.emit(user);
}, e => {
this.loginStatusChanged.emit(null);
});
} private tryGetUser() {
return Observable.fromPromise(this.manager.getUser());
} logout() {
this.manager.signoutRedirect();
}
}

config是针对identity server 4服务器的配置, authorization server的地址是 http://localhost:5000, 登陆成功后跳转后来的地址是: http://localhost:4200/login-callback

其中的UserManager就是oidc-client里面的东西, 它负责处理登录登出和获取当前登录用户等操作.

这里login()方法被调用后会直接跳转到 authorization server的登录页面.

登录成功后会跳转到一个callback页面, 里面需要调用一个callback方法, 这就是loginCallback()方法.

loginStatusChanged是一个EventEmitter, 任何订阅了这个事件的component, 都会在登录用户变化时(登录/退出)触发component里面自定义的事件.

logout()是退出, 调用方法后也会跳转到authorization server的页面.

最后别忘了在app.module里面注册:

  providers: [
ClientService,
AuthService
],

登陆成功后跳转回掉页面

建立一个跳转回掉的component和路由:

ng g c components/loginCallback

修改app.module的路由:

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

打开login-callback.component.ts:

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../services/auth.service';
import { Router } from '@angular/router';
import { User } from 'oidc-client'; @Component({
selector: 'app-login-callback',
templateUrl: './login-callback.component.html',
styleUrls: ['./login-callback.component.css']
})
export class LoginCallbackComponent implements OnInit { constructor(
private authService: AuthService,
private router: Router
) { } ngOnInit() {
this.authService.loginCallBack().subscribe(
(user: User) => {
console.log('login callback user:', user);
if (user) {
this.router.navigate(['/']);
}
}
);
} }

这里主要是调用oidc的回掉函数. 然后跳转到主页.

html:

<p>
登录成功!
</p>

这个html, 基本是看不见的.

修改Navbar

navbar.component.html:

<nav class="navbar navbar-expand-md navbar-light bg-light">
<div class="container">
<a class="navbar-brand" href="#">Client Panel</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button> <div class="collapse navbar-collapse" id="navbarsExampleDefault">
<ul class="navbar-nav mr-auto">
<li *ngIf="isLoggedIn" class="nav-item">
<a class="nav-link" href="#" routerLink="/">Dashboard </a>
</li>
</ul>
<ul class="navbar-nav ml-auto">
<li *ngIf="!isLoggedIn" class="nav-item">
<a class="nav-link" href="#" routerLink="/register">Register </a>
</li>
<li *ngIf="!isLoggedIn" class="nav-item">
<a class="nav-link" href="#" (click)="login()">Login </a>
</li>
<li *ngIf="isLoggedIn" class="nav-item">
<a class="nav-link" href="#" (click)="logout()">Logout </a>
</li>
</ul>
</div>
</div>
</nav>
<br>

主要是检查是否有用户登陆了, 有的话不显示注册和登陆链接, 并且显示退出链接按钮. 没有的话, 则显示注册和登录.

navbar.component.ts:

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from '../../services/auth.service';
import 'rxjs/add/operator/map';
import { User } from 'oidc-client';
import { FlashMessagesService } from 'angular2-flash-messages'; @Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit { public isLoggedIn: boolean;
public loggedInUser: User; constructor(
private authService: AuthService,
private router: Router,
private flashMessagesService: FlashMessagesService
) { } ngOnInit() {
this.authService.loginStatusChanged.subscribe((user: User) => {
this.loggedInUser = user;
this.isLoggedIn = !!user;
if (user) {
this.flashMessagesService.show('登陆成功', { cssClass: 'alert alert-success', timeout: 4000 });
}
});
this.authService.checkUser();
} login() {
this.authService.login();
} logout() {
this.authService.logout();
} }

在ngOnInit里面订阅authservice的那个登录状态变化的事件. 以便切换导航栏的按钮显示情况.

angular的部分先到这, 然后要

修改一个identity server的配置:

在VS2017打开AspNetIdentityAuthorizationServer这个项目的Config.cs文件, 看GetClients()那部分, 里面有一个Client是js client, 我们就用这个....

// JavaScript Client
new Client
{
ClientId = CoreApiSettings.Client.ClientId,
ClientName = CoreApiSettings.Client.ClientName,
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true, RedirectUris = { CoreApiSettings.Client.RedirectUris },
PostLogoutRedirectUris = { CoreApiSettings.Client.PostLogoutRedirectUris },
AllowedCorsOrigins = { CoreApiSettings.Client.AllowedCorsOrigins }, AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
CoreApiSettings.CoreApiResource.Name
}
}

打开CoreApiSettings, 它在SharedSettings这个项目里面:

namespace SharedSettings.Settings
{
public class CoreApiSettings
{
#region CoreApi public static string AuthorizationServerBase = "http://localhost:5000";
public static string CorsPolicyName = "default";
public static string CorsOrigin = "http://localhost:4200";
public static (string Name, string DisplayName) CoreApiResource = ("coreapi", "Core APIs");
public static (string ClientId, string ClientName, string RedirectUris, string PostLogoutRedirectUris, string AllowedCorsOrigins) Client =
("corejs", "Core Javascript Client", "http://localhost:4200/login-callback", "http://localhost:4200/index.html", "http://localhost:4200"); #endregion
}
}

把相应的地址改成和angular auth.service里面config一样的地址才能工作.

这里面使用了C# 7的命名Tuple, 非常好用.

差不多可以了, 运行VS. 同时运行angular项目:

1. 首次浏览:

2. 点击登陆:

点击登陆就跳转到authorization server的登录页面了, 你在这里需要注册一个用户.....

然后输入用户名密码登陆.

3.同意授权

点击yes 同意授权.

4.跳转回angular页面:

首先跳转回的是angular的login-callback路由, 然后瞬间回到了主页:

5. 刷新, 还是可以取得到登录的用户.

但是如果再打开一个浏览器实例就无法取得到登陆用户了, oidc应该是把登陆信息存到了session storage里面.

打开浏览器F12--Application:

可以看到在session storage里面确实有东西, 而 localstorage里面却没有.

今天比较忙, 先写到这... 估计还得写一篇....

使用angular4和asp.net core 2 web api做个练习项目(三)的更多相关文章

  1. 使用angular4和asp.net core 2 web api做个练习项目(一)

    这是一篇学习笔记. angular 5 正式版都快出了, 不过主要是性能升级. 我认为angular 4还是很适合企业的, 就像.net一样. 我用的是windows 10 安装工具: git for ...

  2. 使用angular4和asp.net core 2 web api做个练习项目(四)

    第一部分: http://www.cnblogs.com/cgzl/p/7755801.html 第二部分: http://www.cnblogs.com/cgzl/p/7763397.html 第三 ...

  3. 使用angular4和asp.net core 2 web api做个练习项目(二), 这部分都是angular

    上一篇: http://www.cnblogs.com/cgzl/p/7755801.html 完成client.service.ts: import { Injectable } from '@an ...

  4. angular4和asp.net core 2 web api

    angular4和asp.net core 2 web api 这是一篇学习笔记. angular 5 正式版都快出了, 不过主要是性能升级. 我认为angular 4还是很适合企业的, 就像.net ...

  5. 温故知新,使用ASP.NET Core创建Web API,永远第一次

    ASP.NET Core简介 ASP.NET Core是一个跨平台的高性能开源框架,用于生成启用云且连接Internet的新式应用. 使用ASP.NET Core,您可以: 生成Web应用和服务.物联 ...

  6. 基于ASP.NET Core 创建 Web API

    使用 Visual Studio 创建项目. 文件->新建->项目,选择创建 ASP.NET Core Web 应用程序. 基于 ASP.NET Core 2.0 ,选择API,身份验证选 ...

  7. ASP.NET Core Restful Web API 相关资源索引

    GraphQL 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(上) 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(下) [视频] 使用ASP.NET C ...

  8. 使用 ASP.NET Core 创建 Web API及链接sqlserver数据库

    创建 Web API https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/first-web-api?view=aspnetcore-3.0& ...

  9. ASP.NET Core 中基于 API Key 对私有 Web API 进行保护

    这两天遇到一个应用场景,需要对内网调用的部分 web api 进行安全保护,只允许请求头账户包含指定 key 的客户端进行调用.在网上找到一篇英文博文 ASP.NET Core - Protect y ...

随机推荐

  1. 可能是讲解ARM中断和中断嵌套最通俗易懂的文章

    几天前一个学生问我ARM中断嵌套的问题,我才发现原来在我心中理所当然的事对学生来说理解实属不易.  ARM有七种模式,我们这里只讨论SVC.IRQ和FIQ模式.  我们可以假设ARM核心有两根中断引脚 ...

  2. Fiddler抓包工具使用详解

    一.Fiddler简介 Fiddler是最强大最好用的Web调试工具之一, 它能记录所有客户端和服务器的http和https请求.允许你监视.设置断点.甚至修改输入输出数据.Fiddler包含了一个强 ...

  3. String和StringBuffer分别作为参数传递注意项

    public staticvoid main(){ String s1 = "abc"; StringBuffer sb = new StringBuffer(); sb.appe ...

  4. Vue2.0 探索之路——生命周期和钩子函数

    beforecreate :可以在这加个loading事件 created :在这结束loading,还做一些初始化,实现函数自执行 mounted : 在这发起后端请求,拿回数据,配合路由钩子做一些 ...

  5. NOIP2017SummerTraining0712

    个人感受:打了三个小时不到的第一题,然后也就没有多少时间去搞第二题了,特别是第二题还看到了期望这样的东西,这个难以理解,第三题的树分治,myx大佬说50分好拿,但是我觉得也挺难拿的. 单词检索 时间限 ...

  6. JavaScript高级(01)

    前端开发工具 1.1. WebStorm介绍和下载 l  介绍 WebStorm是JetBrains 推出的一款强大的HTML5编辑工具,拥有丰富的代码快速编辑,可以智能的补全代码.代码格式化.htm ...

  7. IIS7中JS、CSS、Image无法显示和加载解决方案

    前两天把机器从Windows7升级到Windows10,IIS也跟着升级了,在获取项目搭载IIS上发现原有的页面中所有的JS.CSS.Image都无法访问,提示500错误,起初以为是IIS没有装好 重 ...

  8. Win CE 6.0 获取手持机GPS定位1----基础知识 (C#)

    一.GPS全球定位系统的组成 (1)GPS卫星(空间部分) 由沿接近环形的地球轨道运行的24颗卫星组成,位于距地表20200千米的高空,均匀分布在6个轨道面上(每个轨道面4颗),轨道倾角55度.此外, ...

  9. JS数组filter()、map()、some()、every()、forEach()、lastIndexOf()、indexOf()实例

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat=&qu ...

  10. C#仪器数据文件解析-Word文件(doc、docx)

    不少仪器数据报告输出为Word格式文件,同Excel文件,Word文件doc和docx的存储格式是不同的,相应的解析Word文件的方式也类似,主要有以下方式: 1.通过MS Word应用程序的DCOM ...