styles客户端配置(styledsystem)

菲律宾亚星国际登录 25 5

  Angular2是对Angular1的一次彻底的,破坏性的更新。

  相对于Angular1.x,借用某果的广告语,唯一的不同,就是处处都不同。

首先,推荐的语言已经不再是Java,取而代之的Type,(Type = ES6 + 类型系统 + 类型注解), TypeScriipt的类型系统对于开发复杂的单页Web app大有帮助,同时编译成java后的执行效率也比大多数手写java要快。有兴趣的同学可以查阅官方文档:英文传送门| 中文传送门。

得益于彻底重构,性能相对于Angular1.x有了大幅提升,也更适合再全平台部署。

Angular2是基于Component的,Component可以理解为是1.x时代的Controller + $Scope + view

View的很多语法也做了更新,比如<li ng-repeat="movie in vm.movies"></li>变成了 <li *ngFor="let movie of movies"></li>

等等。。

  关于Angular2,强烈建议查阅官方文档:英文传送门| 中文传送门

  废话不多说,接下来的内容中,将介绍如何将 Angular2 整合到 ASP.NET Core 中,并实现一个Anguar2 和 ASP.NET Core Web API 的身份认证。

  注意:本文章属于Step by step + Code Sample教程,且篇幅较长,建议下载本Sample并跟着本文进度自己重做一遍本例,下载完整代码并分析代码结构才有意义,下载地址:How to authorization Angular 2 app with asp.net core web api

  1.前期准备

推荐使用VS2015 Update3或更新的版本完成本示例,下载地址:https://www.visualstudio.com/

你需要安装.NET Core开发环境,这里提供VS版:https://www.microsoft.com/net/core#windows

安装Node.js 版本5.0.0或以上,(在本例中,这个主要是编译Type用的)下载地址:Node.js and NPM

NPM 3.0.0或以上,默认NPM会随着Node.js一并安装完毕。(在本例中,这个主要是下载各种Angular的各个包用的,参考VS中的Nuget)

2.创建项目

  在VS中新建项目,项目类型选择 ASP.NET Core Web Application(.Net Core),输入项目名称为:CSAuthorAngular2InASPNetCore,Template选择为Empty.

  3.在项目中整合Angular2 3.1.配置Startup.cs

  注:添加下面的代码时IDE会报代码错误,这是因为还没有引用对用的包,进入报错的这一行,点击灯泡,加载对应的包就可以了。

  

  (图文无关)

  在ConfigureServices中添加如下代码

  services.AddMvc();

  这里是添加MVC服务

  在Configure中添加如下代码

  app.UseStaticFiles();app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}");});

  第一句是启用静态文件,第二句是应用MVC模式并添加路由配置。

  完整的代码应该是这个样子

  

  3.2.添加控制器以及视图

styles客户端配置(styledsystem)-第1张图片-亚星国际官网

  3.2.1.在项目根目录下添加Controllers目录,并在其中添加一个控制器HomeController.cs,默认代码即可。

  3.2.2.在项目跟目录下创建Views目录,在Views目录中新建目录Home, 最后在Home目录中新建视图Index.cshtml,内容应该是这样:

  

  现在运行项目的话你仅仅能看到一个Loading,再控制台中你还能看到错误,这是因为我们还没有配置Angular。让我们前往wwwroot目录。

  3.3.在项目的wwwroot目录中添加如下结构:

  3.3.1搭建Angular2基础环境

package.json

  

systemjs.config.js

  

tsconfig.js

{ "compileOnSave": true, "compilerOptions": { "target": "es5", "module": "commonjs", "moduleResolution": "node", "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "removeComments": false, "noImplicitAny": false}, "exclude": [ "node_modules"]}

typings.json(注,在最新文档中typings已被npm的@types替代,参见官方文档:文档变更日志)

{ "globalDependencies": { "core-js": "registry:dt/core-js#0.0.0+20160725163759", "jasmine": "registry:dt/jasmine#2.2.0+20160621224255", "node": "registry:dt/node#6.0.0+20160909174046"}}

  右击wwwroot中的Package.json,选择Restore Packages(或者在CMD下进入wwwroot目录,并执行命令 npm install),npm会去下载需要的包,并存储于node_modules目录中。

  

  3.3.2.配置启动文件以启用Angular2

  在wwwroot下新建目录app,app拥有如下文件:

app.component.ts

import { Component } from '@angular/core';@Component({ moduleId: module.id, selector: 'my-app', template: "this is in angular2",})export class AppComponent {}

可以发现被@Component装饰属性装饰了AppComponent,selector指代你Component的占位符,比如本例中你可以再Home/index.cshtml中发现一段这样的标记

<my-app>Loading...</my-app>

  template既为该Component的View,不要忘记moduleId,不添加它会出现很多奇怪的问题。

app.module.ts

import { NgModule } from "@angular/core";import { BrowserModule } from "@angular/platform-browser";import { AppComponent } from "./app.component";@NgModule({ bootstrap: [AppComponent], imports: [ BrowserModule ], declarations: [ AppComponent ]})export class AppModule { }

main.ts

  import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';import { AppModule } from './app.module';const platform =platformBrowserDynamic();platform.bootstrapModule(AppModule);

  基础整合完毕。

  按F5 Debug一下,现在你能再浏览器中看到一句话:this is in angular 2

  

  ---分割线-------------------------------------------------------------------------

  4.实现身份认证

  废了半天劲,看着很傻,没有任何成就感。怎么办,让我们再深入一点,接下来我们来为Angular2完成一个Token base的身份验证,我会把Angular2的routing,data bind,service,http,等等你工作中最常用到的挨个演示一遍。

  4.1.Server端 4.1.1.创建一些辅助类

  4.1.1.1.在项目根目录下创建一个文件夹Auth,并添加RSAKeyHelper.cs以及TokenAuthOption.cs两个文件

  在RSAKeyHelper.cs中

  usingSystem.Security.Cryptography;

  namespaceCSTokenBaseAuth.Auth{

  publicclassRSAKeyHelper {

  publicstaticRSAParameters GenerateKey() {

  using( varkey = newRSACryptoServiceProvider( 2048)) { returnkey.ExportParameters( true); } } }}

  在TokenAuthOption.cs中

  usingSystem;

  usingMicrosoft.IdentityModel.Tokens;

  namespaceCSTokenBaseAuth.Auth{

publicclassTokenAuthOption {

publicstaticstringAudience { get; } = "ExampleAudience";

publicstaticstringIssuer { get; } = "ExampleIssuer";

publicstaticRsaSecurityKey Key { get; } = newRsaSecurityKey(RSAKeyHelper.GenerateKey()); publicstaticSigningCredentials SigningCredentials { get; } = newSigningCredentials(Key, SecurityAlgorithms.RsaSha256Signature);

publicstaticTimeSpan ExpiresSpan { get; } = TimeSpan.FromMinutes(20); }}

  4.1.1.2.在项目根目录下创建目录Model,并在其中添加RequestResult.cs,代码应该是这样。

  publicclassRequestResult{

  publicRequestState State { get; set; }

  publicstringMsg { get; set; }

  publicObject Data { get; set; }}

styles客户端配置(styledsystem)-第1张图片-亚星国际官网

  publicenumRequestState{ Failed = - 1, NotAuth = 0, Success = 1}4.1.2更新Startup.cs

  在ConfigureServices中添加如下代码:

  services.AddAuthorization(auth => { auth.AddPolicy("Bearer", newAuthorizationPolicyBuilder() .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme?) .RequireAuthenticatedUser().Build());});

  这里是添加身份认证服务

  在Configure方法中添加如下代码:

  app.UseExceptionHandler(appBuilder => { appBuilder.Use(async (context, next) => { varerror = context.Features[ typeof(IExceptionHandlerFeature)] as IExceptionHandlerFeature; //when authorization has failed, should retrun a json message to clientif(error != null&& error.Error is SecurityTokenExpiredException) { context.Response.StatusCode = 401 ; context.Response.ContentType = "application/json" ; await context.Response.WriteAsync(JsonConvert.SerializeObject(newRequestResult { State = RequestState.NotAuth, Msg = "token expired" })); } //when orther error, retrun a error message json to clientelseif(error != null&& error.Error != null) { context.Response.StatusCode = 500 ; context.Response.ContentType = "application/json" ; await context.Response.WriteAsync(JsonConvert.SerializeObject(newRequestResult { State = RequestState.Failed, Msg = error.Error.Message })); } //when no error, do next.elseawait next(); });});

styles客户端配置(styledsystem)-第1张图片-亚星国际官网

  本段是Handle当身份认证失败时抛出的异常,并返回合适的json

  在相同的方法中添加另外一段代码:

  

styles客户端配置(styledsystem)-第1张图片-亚星国际官网

  本段代码是应用JWTBearerAuthentication身份认证。

  4.1.3.TokenAuthController.cs

  在Controllers中新建一个Web API Controller Class,命名为TokenAuthController.cs。我们将在这里完成登录授权,

  在同文件下添加两个类,分别用来模拟用户模型,以及用户存储,代码应该是这样:

  publicclassUser{

  publicGuid ID { get; set; }

  publicstringUsername { get; set; }

  publicstringPassword { get; set; }}

  publicstaticclassUserStorage{

  publicstaticList<User> Users { get; set; } = newList<User> { newUser {ID=Guid.NewGuid(),Username= "user1",Password = "user1psd"}, newUser {ID=Guid.NewGuid(),Username= "user2",Password = "user2psd"}, newUser {ID=Guid.NewGuid(),Username= "user3",Password = "user3psd"} };}

  接下来在TokenAuthController.cs中添加如下方法

  

  该方法仅仅只是生成一个Auth Token,接下来我们来添加另外一个方法来调用它

  在相同文件中添加如下代码

  

  接下来我们来完成授权部分,在相同的文件中添加如下代码:

styles客户端配置(styledsystem)-第1张图片-亚星国际官网

  publicstringGetUserInfo(){ varclaimsIdentity = User.Identity asClaimsIdentity; returnJsonConvert.SerializeObject( newRequestResult { State = RequestState.Success, Data = new{ UserName = claimsIdentity.Name } });}

  为方法添加装饰属性

  [HttpGet][Authorize("Bearer")]

  第二行代码说明这个action需要身份验证。

  该文件完整的代码应该是这个样子:

  usingSystem;

  usingSystem.Collections.Generic;

  usingSystem.Linq;

  usingMicrosoft.AspNetCore.Mvc;

  usingCSAuthorAngular2InASPNetCore.Auth;

  usingSystem.IdentityModel.Tokens.Jwt;

  usingNewtonsoft.Json;

  usingSystem.Security.Claims;

  usingSystem.Security.Principal;

  usingMicrosoft.IdentityModel.Tokens;

  usingCSAuthorAngular2InASPNetCore.Model;

  usingMicrosoft.AspNetCore.Authorization;

  namespaceCSAuthorAngular2InASPNetCore.Controllers{ [Route("api/[controller]")]

  publicclassTokenAuthController : Controller { [HttpPost]

  publicstringGetAuthToken([FromBody]User user) {

  varexistUser = UserStorage.Users.FirstOrDefault(u => u.Username == user.Username && u.Password == user.Password); if(existUser != null) {

  varrequestAt = DateTime.Now; varexpiresIn = requestAt + TokenAuthOption.ExpiresSpan;

  vartoken = GenerateToken(existUser, expiresIn); returnJsonConvert.SerializeObject( newRequestResult { State = RequestState.Success, Data = new{ requertAt = requestAt, expiresIn = TokenAuthOption.ExpiresSpan.TotalSeconds, tokeyType = TokenAuthOption.TokenType, accessToken = token } }); }

  else{

  returnJsonConvert.SerializeObject( newRequestResult { State = RequestState.Failed, Msg = "Username or password is invalid"}); } }

  privatestringGenerateToken(User user, DateTime expires) { varhandler = newJwtSecurityTokenHandler(); ClaimsIdentity identity = newClaimsIdentity(

  newGenericIdentity(user.Username, "TokenAuth"), new[] { newClaim( "ID", user.ID.ToString()) } );

  varsecurityToken = handler.CreateToken( newSecurityTokenDeor { Issuer = TokenAuthOption.Issuer, Audience = TokenAuthOption.Audience, SigningCredentials = TokenAuthOption.SigningCredentials, Subject = identity, Expires = expires }); returnhandler.WriteToken(securityToken); } [HttpGet] [Authorize("Bearer")] publicstringGetUserInfo() { varclaimsIdentity = User.Identity asClaimsIdentity; returnJsonConvert.SerializeObject( newRequestResult { State = RequestState.Success, Data = new{ UserName = claimsIdentity.Name } }); } }

  publicclassUser {

  publicGuid ID { get; set; }

  publicstringUsername { get; set; } publicstringPassword { get; set; } }

  publicstaticclassUserStorage {

  publicstaticList<User> Users { get; set; } = newList<User> { newUser {ID=Guid.NewGuid(),Username= "user1",Password = "user1psd"}, newUser {ID=Guid.NewGuid(),Username= "user2",Password = "user2psd"}, newUser {ID=Guid.NewGuid(),Username= "user3",Password = "user3psd"} }; }}

  4.2Angular2端

  4.2.1创建View Model

  在wwwroot/app下创建一个目录:_model, 并添加一个Type文件RequestResult.ts,内容应该是这样。

  export class RequestResult { State: number; Msg: string; Data: Object;}

  4.2.2创建Service

  在wwwroot/app下创建一个目录:_services,并添加一个Type文件auth.service.ts,内容应该是这样。

  

  

  本文件主要用来完成登录以及登录验证工作,之后该service将可以被注入到Component中以便被Component调用。

  注:主要的逻辑都应该写到service中

  4.2.3.创建Component

  4.2.3.1.在wwwroot/app下创建一个目录home,该目录用来存放HomeComponent,home应拥有如下文件:

home.component.ts

  

查阅代码,在@Component中指定了View以及style。

  AuthService被在构造方法中被注入了本Component,ngOnInit是接口OnInit的一个方法,他在Component初始化时会被调用。

style.css

  /*styles of this view*/

  本例中没有添加任何样式,如有需要可以写在这里。

view.html

  <div *ngIf="isLogin"><h1>Hi <span>{{userName}}</span></h1></div><div *ngIf="!isLogin"><h1>please login</h1><a routerLink="/login">Login</a></div>

  *ngIf=""是Angular2 的其中一种标记语法,作用是当返回真时渲染该节点,完整教程请参阅官方文档。

  4.2.3.2.在wwwroot/app下创建目录Login,该目录用来存放LoginComponent,文件结构类似于上一节。

login.component.ts

  

style.css

styles客户端配置(styledsystem)-第1张图片-亚星国际官网

/*styles of this view*/

view.html

  <table><tr><td>userName:</td><td><input [(ngModel)]="userName"placeholder="useName:try type user1"/></td></tr><tr><td>userName:</td><td><input [(ngModel)]="password"placeholder="password:try type user1psd"/></td></tr><tr><td></td><td><input type="button"(click)="login()"value="Login"/></td></tr></table>

4.2.4.应用路由

  路由是切换多页面用的。

  在wwwroot/app下新建一个Type文件,命名为app-routing.module.ts,内容应该是这个样子。

  

  接下来我们来应用这个路由,

  打开app.module.ts,更新代码如下:

  

  NgModule和BrowserModule你可以理解为基础模块,必加的。

  HttpModule是做http请求用的。

  FormsModule是做双向数据绑定用的,比如下面这样的,如果想把数据从view更新到component,就必须加这个。

  <input [(ngModel)]="userName"placeholder="useName:try type user1"/>

  AppRoutingModule即为我们刚才添加的路由文件。

  AuthService是我们最早添加的service文件。

  AppComponent是我们最初添加的那个app.component.ts里的那个component.

  HomeComponent,LoginComponent同上。

  最后我们再app.component.ts中添加路由锚点,

  把template的值为 "<router-outlet></router-outlet>"

  完整的代码应该是这样:

  import { Component } from '@angular/core' ;@Component({ moduleId: module.id, selector: 'my-app' , template: "<router-outlet></router-outlet>" ,})export class AppComponent {}

  router-outlet是路由锚点的关键词。

  至此,所有代码完成,F5调试吧。

  完整的Angular2的入门教程,请参阅官方文档的《英雄指南》:中文传送门| 英文传送门

  关于本例完整的代码以及调试运行步骤,请访问:How to authorization Angular 2 app with asp.net core web api

  相关文章

Angular 2与Type概览

Angular发布1.5正式版,专注于向Angular 2的过渡

我为什么选择Angular 2?

ASP.NET Core loves Java

使用 JavaService 在.NET Core 里实现DES加密算法

  原文地址:https://www.cnblogs.com/onecodeone/p/6062203.html

  .NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

标签: styles客户端配置

发表评论 (已有5条评论)

评论列表

2025-04-17 04:19:21

   本文件主要用来完成登录以及登录验证工作,之后该service将可以被注入到Component中以便被Component调用。  注:主要的逻辑都应该写到service中  4.2.3.创建Component   4.2.3.1.在w

2025-04-17 07:56:57

l;  usingMicrosoft.IdentityModel.Tokens;  usingCSAuthorAngular2InASPNetCore.Model;  usingMicrosoft.AspNetCore.Authorization;  namespaceCSAut

2025-04-17 10:34:53

t;  *ngIf=""是Angular2 的其中一种标记语法,作用是当返回真时渲染该节点,完整教程请参阅官方文档。  4.2.3.2.在wwwroot/app下创建目录Login,

2025-04-17 07:03:21

,(Type = ES6 + 类型系统 + 类型注解), TypeScriipt的类型系统对于开发复杂的单页Web app大有帮助,同时编译成java后的执行效率也比大多数手写java要快。有兴趣的同

2025-04-17 12:03:08

wList<User> { newUser {ID=Guid.NewGuid(),Username= "user1",Password = "user1psd"}, newUser {ID=Guid.NewGuid(),Username= "user2",Password = "use