博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用angular4和asp.net core 2 web api做个练习项目(三)
阅读量:6346 次
发布时间:2019-06-22

本文共 7485 字,大约阅读时间需要 24 分钟。

第一部分: 

第二部分: 

后台代码: 

前台代码: 

 

下面将开发登陆和授权的部分, 这里要用到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
; 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:

登录成功!

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

修改Navbar

navbar.component.html:

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

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里面却没有.

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

 

转载地址:http://pncla.baihongyu.com/

你可能感兴趣的文章
C# 中out,ref,params参数的使用
查看>>
Java统计文件夹中文件总行数
查看>>
python之基本数据类型及深浅拷贝
查看>>
将bootstrap弹出框的点击弹出改为鼠标移入弹出
查看>>
SKF密码设备研究
查看>>
数据对象映射模式(通过工厂模式和注册树模式)v2
查看>>
4939 欧拉函数[一中数论随堂练]
查看>>
MySQL笔记(一)
查看>>
spring boot 包jar运行
查看>>
18年秋季学习总结
查看>>
Effective前端1:能使用html/css解决的问题就不要使用JS
查看>>
网络攻防 实验一
查看>>
由莫名其妙的错误开始---浅谈jquery的dom节点创建
查看>>
磨刀-CodeWarrior11生成的Makefile解析
查看>>
String StringBuffer StringBuilder对比
查看>>
bootstrap随笔点击增加
查看>>
oracle 中proc和oci操作对缓存不同处理
查看>>
[LeetCode] Spiral Matrix 解题报告
查看>>
60906磁悬浮动力系统应用研究与模型搭建
查看>>
指纹获取 Fingerprint2
查看>>