ASP.NET Identity Core入門 - 1

by vivid 10. 一月 2018 03:17

.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號:
N180119101
出刊日期: 2018/1/10

在這篇文章中,將要介紹如何在ASP.NET Core網站專案中,使用ASP.NET Core Identity設計會員系統,以完成會員註冊與會員登入的功能。

建立ASP.NET Core Web Application專案

點選Visual Studio 2017開發工具的「File」-「New」-「Project」項目,在「New Project」對話盒中,確認視窗上方.NET Framework的目標版本為「.NET Framework 4.6.1」或以上版本,選取左方「Installed」清單- 「Templates」-「Visual C#」程式語言,從「.NET Core」分類中,選取「ASP.NET Core Web Application」,請參考下圖所示,設定專案名稱以及專案存放路徑後按下「OK」鍵。

clip_image002

圖 1:建立「ASP.NET Core Web Application」專案。

在「New ASP.NET Core Web Application」對話盒中,確認左上方的清單選取「.NET Core」,右上方的清單ASP.NET Core版本為「ASP.NET Core 2.0」,選取下方的「Empty」樣版專案,清除勾選下方的「Enable Docker Support」核取方塊,確定右方的「Authentication」項目設定為「No Authentication」,然後按下「OK」按鈕建立專案,請參考下圖所示:

clip_image004

圖 2:選取「Empty」樣版專案。

預設專案會參考「Microsoft.AspNetCore.All」套件,可以從Visual Studio 2017開發工具「Solution Explorer」視窗 - 「專案名稱」-「Dependencies」- 「Nuget」- 展開「Microsoft.AspNetCore.All(2.0.0)」項目,這個項目中預設就包含「Microsoft.AspNetCore.Identity (2.0.0)」與「Microsoft.AspNetCore.Identity.EntityFrameworkCore (2.0.0)」子項目,請參考下圖所示:

clip_image006

圖 3:預設專案參考「Microsoft.AspNetCore.All」套件。

Microsoft.AspNetCore.Identity命名空間下定義以下類別以幫助帳號建置與管理:

  • IdentityUser :代表個別使用者資訊。
  • IdentityRole:代表使用者角色(Role)資訊。
  • IdentityUserRole:用來定義使用者隸屬於特定的群組。
  • IdentityUserClaim:代表特定的使用者宣告(Claim)。
  • IdentityUserLogin:代表使用者登入。
  • IdentityUserToken:代表一個使用者的驗證(authentication)
  • IdentityRoleClaim:代表特定的角色宣告(Claim)。

你可以直接使用這些類別,或是繼承這些類別,再擴充它們以自訂功能。

建立模型

在本文的範例中,要擴充IdentityUser,讓使用者在註冊會員帳號資料時,除了將電子郵件當帳號之外,可以額外設定一個簡短的别名(NickName),以便在網站之中使用。首先先在專案中建立模型,一般建議將模型程式碼放在Models資料夾中。

從「Solution Explorer」視窗,專案名稱上方按滑鼠右鍵,從快捷選單選擇「Add」- 「New Folder」選項,將新建立的資料夾命名為「Models」,請參考下圖所示:

clip_image008

圖 4:建立新資料夾。

從「Solution Explorer」視窗 -「Models」資料夾上方,按滑鼠右鍵,從快捷選單選擇「Add」- 「Class」,選取「Code」分類下的「Class」項目,然後在下方將「Name」設定為「ApplicationUser」最後按下「Add」按鈕新增類別,請參考下圖所示:

clip_image010

圖 5:新增類別。

修改「ApplicationUser」類別程式碼,讓類別繼承「IdentityUser」類別,並在其中新增一個NickName屬性,請參考下列程式碼:

using Microsoft.AspNetCore.Identity;

namespace IdentityDemo.Models {
  public class ApplicationUser : IdentityUser {
    public string NickName { get; set; }
  }
}

 

設定連接字串

會員註冊資料需儲存到資料庫。ASP.NET Core Identity可以搭配Microsoft.AspNetCore.Identity.EntityFramework套件利用Entity Framework Core將資料儲存到SQL Server資料庫之中。我們先利用appsettings.json組態檔案設定資料庫連接字串,從「Solution Explorer」視窗,專案名稱上方按滑鼠右鍵,從快捷選單選擇「Add」- 「New Item」項目,開啟「Add New Item」對話盒,選取左方「Web」分類下的「ASP.NET Configuration File」,設定名稱為「appsettings.json」,然後按下「Add」按鈕,建立檔案,請參考下圖所示:

clip_image012

圖 6:加入「appsettings.json」檔案設定連接字串。

預設「appsettings.json」檔案之中將產生以下連接字串設定:


{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=_CHANGE_ME;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

讓我們修改資料庫伺服器的名稱為「Server=(localdb)\\MSSQLLocalDB」;資料庫的名稱為「IdentityDemo」,並使用Windows驗證連接到資料庫:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=IdentityDemo;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

 

預設透過Microsoft.AspNetCore.Identity.EntityFrameworkCore 套件將使用者的帳號資料儲存到SQL Server資料庫之中。你可以繼承Microsoft.AspNetCore.Identity.EntityFrameworkCore命名空間下的IdentityDbContext<TUser>類別,它又繼承自Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext類別,負責處理資料存取相關的細節。

設計IdentityDbContext類別

在專案中加入Data資料夾,從Visual Studio 2017開發工具 -「Solution Explorer」視窗 - 專案名稱上方按滑鼠右鍵,從快捷選單選擇「Add」- 「New Folder」選項,將新建立的資料夾命名為「Data」。

從「Solution Explorer」視窗 -「Data」資料夾上方,按滑鼠右鍵,從快捷選單選擇「Add」- 「Class」,選取「Code」分類下的「Class」項目,然後在下方將「Name」設定為「ApplicationDbContext」最後按下「Add」按鈕新增類別,請參考下圖所示:

clip_image014

圖 7:新增類別。

修改「ApplicationDbContext」類別程式碼,使其繼承自「IdentityDbContext<ApplicationUser>」類別,並在類別中定義一個建構函式,然後使用相依性注入(Depenency Injection)在建構函式中插入服務「DbContextOptions<ApplicationDbContext>」,請參考以下程式碼:

using IdentityDemo.Models;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace IdentityDemo.Data {
  public class ApplicationDbContext : IdentityDbContext<ApplicationUser> {
    public ApplicationDbContext( DbContextOptions<ApplicationDbContext> options ) : base( options ) {
    }
    protected override void OnModelCreating( ModelBuilder builder ) {
      base.OnModelCreating( builder );
    }
  }
}


在建構函式插入「DbContextOptions<ApplicationDbContext>」的目的是要讀取「appsettings.json」檔案中的設定連接字串。檢視「Program.cs」的「Main」方法,叫用「WebHost.CreateDefaultBuilder」方法設定環境:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace IdentityDemo {
  public class Program {
    public static void Main( string [] args ) {
      BuildWebHost( args ).Run( );
    }

    public static IWebHost BuildWebHost( string [] args ) =>
        WebHost.CreateDefaultBuilder( args )
            .UseStartup<Startup>( )
            .Build( );
  }
}


檢視Github  上這個方法的原始程式碼如下,叫用「IConfigurationBuilder」的「AddJsonFile」方法來讀取「appsettings.json」檔案:

public static IWebHostBuilder CreateDefaultBuilder( string [] args ) {
  var builder = new WebHostBuilder( )
      .UseKestrel( )
      .UseContentRoot( Directory.GetCurrentDirectory( ) )
      .ConfigureAppConfiguration( ( hostingContext , config ) => {
        var env = hostingContext.HostingEnvironment;

        config.AddJsonFile( "appsettings.json" , optional: true , reloadOnChange: true )
                    .AddJsonFile( $"appsettings.{env.EnvironmentName}.json" , optional: true , reloadOnChange: true

        if ( env.IsDevelopment( ) ) {
          var appAssembly = Assembly.Load( new AssemblyName( env.ApplicationName ) );
          if ( appAssembly != null ) {
            config.AddUserSecrets( appAssembly , optional: true );
          }
        }

        config.AddEnvironmentVariables( );

        if ( args != null ) {
          config.AddCommandLine( args );
        }
      } )
      .ConfigureLogging( ( hostingContext , logging ) => {
        logging.UseConfiguration( hostingContext.Configuration.GetSection( "Logging" ) );
        logging.AddConsole( );
        logging.AddDebug( );
      } )
      .UseIISIntegration( )
      .UseDefaultServiceProvider( ( context , options ) => {
        options.ValidateScopes = context.HostingEnvironment.IsDevelopment( );
      } )
      .ConfigureServices( services => {
        services.AddTransient<IConfigureOptions<KestrelServerOptions> , KestrelServerOptionsSetup>( );
      } );

  return builder;
}

稍後在Startup類別中再進行組態。

 

設定服務(Service)與中介軟體(Middleware)

修改「Startup.cs」檔案中「Startup」類別的程式碼,利用建構函式插入「IConfiguration」以讀取組態檔案的內容,在「ConfigureServices」方法中加入程式碼設定ASP.NET Core Identity,最後在「Configure」方法中叫用「UseAuthentication」方法將ASP.NET Core Identity加入請求管線(request pipeline),請參考以下程式碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using IdentityDemo.Data;
using IdentityDemo.Models;
using Microsoft.Extensions.Configuration;

namespace IdentityDemo {
  public class Startup {

    public IConfiguration Configuration { get; }

    public Startup( IConfiguration configuration ) {
      Configuration = configuration;
    }

    public void ConfigureServices( IServiceCollection services ) {

      services.AddDbContext<ApplicationDbContext>( options =>
        options.UseSqlServer( Configuration.GetConnectionString( "DefaultConnection" ) ) );

      services.AddIdentity<ApplicationUser , IdentityRole>( )
                            .AddEntityFrameworkStores<ApplicationDbContext>( )
                            .AddDefaultTokenProviders( );
      services.AddMvc( );

    }

    public void Configure( IApplicationBuilder app , IHostingEnvironment env ) {
      if ( env.IsDevelopment( ) ) {
        app.UseDeveloperExceptionPage( );
      }

      app.UseAuthentication( );
      app.UseMvcWithDefaultRoute( );
    }
  }
}

 

選取Visual Studio 開發工具「Build」-「Build Solution」項目編譯目前的專案,確認程式碼能正確編譯。

EF Core移轉(Migrations)

接下來我們利用EF Core移轉(Migrations)功能來建立資料庫,預設專案範本引用的「Microsoft.AspNetCore.All」套件中包含「Microsoft.EntityFrameworkCore.Tools」套件,不需要手動安裝。

編輯.csproj檔案,從「Solution Explorer」視窗專案名稱上方按滑鼠右鍵,從快捷選單選擇「Edit XXX.csproj」項目,請參考圖所示:

clip_image016

圖 8:編輯專案檔案。

在.csproj檔案加入以下DotNetCliToolReference設定,這樣才可以透過Entity Framework Core工具程式來操作資料庫:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework> netcoreapp2.0 </TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <DotNetCliToolReference Include = "Microsoft.EntityFrameworkCore.Tools.DotNet" Version = "2.0.0" />
  </ItemGroup>
 
  <ItemGroup>
    <Folder Include = "wwwroot\" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include = "Microsoft.AspNetCore.All" Version = "2.0.0" />
  </ItemGroup>

</Project>

 

開啟「Developer Command Prompt for VS 2017」命令提示字元,利用cd指令切換到csproj檔案所在的位置:

cd csproj檔案所在的資料夾

輸入以下指令啟用移轉功能:

dotnet ef migrations add initial

執行結果參考如下:

clip_image018

圖 9:使用EF Core移轉(Migrations)。

完成後,專案中將會建立一個「Migrations」資料夾,包含多個C#檔案,其中包含建置資料表的相關資訊,請參考下圖所示:

clip_image020

圖 10:EF Core移轉檔案。

接著在「Developer Command Prompt for VS 2017」命令提示字元執行以下指令:

dotnet ef database update

執行結果參考如下:

clip_image022

圖 11:更新資料庫。

開啟「Server Explorer」視窗,在「Data Connections」項目上按滑鼠右鍵,從快捷選單之中選取「Add Connection」項目,請參考下圖所示:

clip_image024

圖 12:建立「Data Connections」連線。

在「Add Connection」視窗中,設以下屬性:

1. 資料來源 (Data Source) :Microsoft SQL Server (SqlClient)。

2. 「Server name」欄位:輸入「(localdb)\MSSQLLocalDB」。

3. 「Authentication」:選取「Windows Authentication」。

4. 「Select or enter a database name」欄位:選擇「IdentityDemo」資料庫,請參考下圖所示:

clip_image026

圖 13:設定連接資料庫資訊。

檢視新建立的資料表與欄位資訊,展開「Server Explorer」視窗-「Data Connections」-「IdentityDemo」資料庫 -「Tables」- 「AspNetUsers」資料表,在「AspNetUsers」資料表上按滑鼠右鍵,從快捷選單中選取「Open Table Definition」,請參考下圖所示:

clip_image028

圖 14:檢視新建立的資料表與欄位資訊。

接著便會顯示資料表結構,包含NickName欄位對應到ApplicationUser類別中定義的屬性,請參考下圖所示:

clip_image030

圖 15:檢視ApplicationUsers資料表欄位資訊。

完成資料庫結構之後,下一步就可以在MVC網站中使用它。

Tags:

.NET Magazine國際中文電子雜誌 | ASP.NET Core MVC | 許薰尹Vivid Hsu

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List