asp.net core2.1 Identityチュートリアル(途中まで)やってみた

# 概要

[Microsoft本家様のログイン機能(Identity)チュートリアル](https://docs.microsoft.com/ja-jp/aspnet/core/security/authentication/identity?view=aspnetcore-2.1&tabs=visual-studio)を行いました。

まだ新しい機能なのか、ところどころ行き詰ったので、
私用備忘録の補足記事です。

## 環境
- Microsoft Visual Studio Community 2017 Version 15.8.1
- Microsoft.NET Framework Version 4.7.03056
- ASP.NET Core2.1

# チュートリアルをやってみた
## 補足１：Id データベースが表示されない
本家の[ASP.NET Core Identity の概要](https://docs.microsoft.com/ja-jp/aspnet/core/security/authentication/identity?view=aspnetcore-2.1&tabs=visual-studio)にて、
「Id データベースを表示します。」
という項目があるのですが、データベース無い！というときがあります。

その場合は、パッケージマネージャーコンソールで、
データベースをアップデートすると、作られたりします。
 
### 手順
下部のタブにある「パッケージ マネージャ コンソール」にて、
下記を行う。

```
PM> Add-Migration 
PM> Update-Database
```

なお、「パッケージ マネージャ コンソール」がない場合は、
ツール -> NuGet パッケージマネージャ -> パッケージ マネージャ コンソール
を選択するとできるようになるかと。

また、なんかバージョン古い的なエラーが出た場合は、
[こちらのサイト](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.Tools/)にて、
下記を先に実行するとできるようになるかも。

```
PM>Install-Package Microsoft.EntityFrameworkCore.Tools -Version 2.1.4
```

### 注意
このあとの作業で、スキャンフォールディングってのがあるのですが、
この際にもまたデータベースを作成するので、
もしかしたら上記の作業は必要ないかもしれません。
データベースが二つできてしまいます。

## 補足２：スキャフォールディングのDB設定

手準にとってひとまず[スキャフォールディング](https://docs.microsoft.com/ja-jp/aspnet/core/security/authentication/scaffold-identity?view=aspnetcore-2.1&tabs=visual-studio)を行います。
スキャンフォールディングするときは、
プロジェクトを右クリックして、
追加 -> 新規スキャフォールディングアイテムを選択したら、
左にあるリストの「ID」を選択します。（多分手順ではIdentityってなってる）

この時、ファイルはとりあえず全選択してOKです。
というか、多分ですが、ファイルをすべて全選択しないと、
ログイン画面とかをカスタマイズできません。
選択したファイルだけ、既存のソースコードをオーバーライドする形で適応されるので、
とりあえず全部選択するば、全部いじれるようになれます。
（という認識ですが、認識違いだったらご指摘お願いします・・・）

手順通りに、「データコンテキストクラス」も追加しておきます。
※後で使います。


ここで、補足１でやったようなコマンドがでてきます。

```
PM> Add-Migration CreateIdentitySchema
PM> Update-Database
```
ですが、このままだと動かない場合があります。
エラー文になにやらContextを指定しろとあるので、
スキャンフォールディングした際に設定した、データコンテキストクラスを設定します。
例では、WebApp1Contextというコンテキストです。
忘れてしまった場合は、
フォルダ(ソリューションエクスプローラー)の、
Areas\Identity\Dataの中に「〇〇Context.cs」みたいなファイルがあると思うので、
それを指定します。

```
PM> Add-Migration CreateIdentitySchema -Context WebApp1Context
PM> Update-Database -Context WebApp1Context
```

実際に起動して、ログインしたり、ログイン画面をいじったりしてみてください。

## 補足３：カスタムユーザーはShared_LoginPartial.cshtmlの修正が必要
今回行ったのは[Idへのカスタム ユーザーデータの追加](https://docs.microsoft.com/ja-jp/aspnet/core/security/authentication/add-user-data?view=aspnetcore-2.1&tabs=visual-studio)までです。

ここでは、自動生成されるログインユーザーに好きなカラムを追加できるというものです。

既存では、メールアドレスや電話番号など、
基本的なログインユーザー用のカラムがありますが、
それに加えて、性別など生年月日など、カラムを追加したいときは追加が可能になっています。
ただ、ここでもまたスキャフォールディングをするので、
補足２でスキャフォールディングを行った場合は、
新しくプロジェクトを作成し、スキャフォールディングの手順を飛ばし、
カスタムユーザー追加の手順を行うことを進めます。

（スキャフォールディングの後に、新たにカスタムカラムを追加する方法は、
私もわかっていません・・・）

補足２の時は、スキャフォールディング時に「データコンテキストクラス」を追加しましたが、
それに加えて、「データコンテキストクラス」の下にある項目の、
「ユーザークラス」も追加します。

ユーザークラスをついかすることで、カスタムカラムを追加できます。

おなじみの

```
PM> Add-Migration CustomUserData
PM> Update-Database
```
ですが、またコンテキストを指定します。
ちょっとここの記憶がおぼろげですが、多分、
補足２と同様、スキャフォールディング時の「データコンテキストクラス」に設定したものを指定します。

```
PM> Add-Migration CustomUserData　-Context WebApp1Context
PM> Update-Database　-Context WebApp1Context
```
こんな感じですね。
実際にデータベースを確認すると、追加したカラムdbo.AspNetUsersに反映されていると思います。

そして、多分、このままだと動きません。
これは手順にないのですが、Views\Shared\_LoginPartial.cshtmlを修正する必要があります。
参考ページ：https://github.com/aspnet/Mvc/issues/7856
IdentityUserの部分をAreas\Identity\Data\〇〇User.csにします。
例では、WebApp1Userです。
これは、スキャフォールディングした際の「ユーザークラス」だったかと思います。

```C#:_LoginPartial.cshtml
@using Microsoft.AspNetCore.Identity
@using WebApp1.Areas.Identity.Data

@*
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager
*@
@inject SignInManager<WebApp1User> SignInManager
@inject UserManager<WebApp1User> UserManager
```

ここまでやったら、多分動くかと！
今回チュートリアルを行ったのはここまでです。
なお、メール認証は、うまくいかず諦めました。
チュートリアルで紹介されているSendGridは有料らしいので・・・

うろ覚えの部分もありますが、
この補足分でチュートリアルはできるんじゃないかと思います。
文章ばっかりですが、自分のための備忘録ということで。


## エラー対応：InvalidOperationException: Scheme already exists: Identity.Application
手順通りにやってけば躓かないかもしれませんが、
*InvalidOperationException: Scheme already exists: Identity.Application*
みたいなエラーは、Startup.csとIdentityHostingStartup.csでDBの設定を二重で行っている場合があります。
自分の必要とする設定だけ残してください。