ASP.NETのIdentityテーブルについて

マイグレーションの時に、列の文字数長さの設定でmaxの部分でエラーになるので、それぞれにどんな情報が入っていて、何を設定すべきか調べてみた。

Identityで生成されるテーブルとそれらの関係は以下のとおり

7つのテーブルがあり、Userとそれに関連するテーブルが4つと
Roleとそれに関するテーブルが2つと
UserとRoleを結ぶテーブルが1つの計7つで構成されている

AspNetUsersテーブル

AspNetUserテーブルは、ユーザーに関する主要な情報が格納

列名 nvarchar(max) 内容
Id ユーザーの一意の識別子。通常はGUID(ハイフンあり)
UserName ユーザーのログイン名
NormalizedUserName 検索などの比較で効率的に行うための正規化(大文字)
Email メールアドレス
NormalizedEmail 検索などの比較で効率的に行うための正規化(大文字)
EmailConfirmed メールアドレスによる確認ができたかを示すブール値
PasswordHash ユーザーパスワード(Hash値)
SecurityStamp セキュリティ目的で使用される一意の値
ConcurrencyStamp 同時実行制御に使用。GUIDが使われる
PhoneNumber 電話番号
PhoneNumberConfirmed 電話番号による確認ができたかを示すブール値
TwoFactorEnabled 二要素認証が有効かどうかを示すブール値
LockoutEnd アカウントロックアウトが終了する日時
LockoutEnabled アカウントのロックアウトが有効かどうかのブール値
AccessFailedCount ログイン失敗回数

・AIの見解
PasswordHash・・・一般的なハッシュアルゴリズム(例:SHA256)の出力は64文字程度です。将来的なハッシュアルゴリズムの変更に対応できる余裕を持たせて128文字程度が妥当ではないか

SecurityStamp・・・セキュリティスタンプはGUIDベースで生成されることが多いです。GUIDの文字列表現は通常36文字です。よって36文字

ConcurrencyStamp・・・同時実行制御に使用されるタイムスタンプです。通常GUIDが使用される。GUIDの文字列表現は通常36文字。よって36文字

PhoneNumber・・・国際電話番号を考慮すると15桁程度。中継電話会社経由の番号だと16桁になることもある。電話番号の桁数はいつかわってもおかしくないので多少余裕をもたせるとよさそう。よって20文字

AspNetUserClaimsテーブル

AspNetUserClaimsテーブルは、ーザーに関連付けられたクレーム情報が格納

列名 nvarchar(max) 内容
Id プライマリキーとして機能する一意の識別子
UserId クレームを設定するUserId
ClaimType クレームの種類や名前
ClaimValue クレームの値

クレームは、ユーザーはロールといった概念のほかに情報を追加し細かい認証の制御を行うために使用する
よって、クレームの種類や値を設定するのは開発者次第のためお好きな文字数を設定すればよい
長い名称を使うことなければ64文字とかで十分かなと

AspNetUserLoginsテーブル

AspNetUserLoginsテーブルは、外部認証プロバイダーを使用してログインしたユーザーの情報が格納

列名 nvarchar(max) 内容
LoginProvider 外部認証プロバイダーの名前(例:Google、Facebook、Microsoft等)
ProviderKey 認証プロバイダーがユーザーに割り当てた一意の識別子
ProviderDisplayName 認証プロバイダーの表示名を格納
UserId 該当するUserId

ProviderDisplayNameは、例えばGoogleの認証だとGoogleが格納されています。そこまで長い名前は入るとおもえないので、64文字程度もあれば十分かなと

AspNetUserTokensテーブル

AspNetUserTokensテーブルは、ユーザーに関連する各種トークン情報が格納

列名 nvarchar(max) 内容
UserId AspNetUsersテーブルのIdに対応する、ユーザーの一意の識別子
LoginProvider トークンを生成したプロバイダーの名前を指定
Name トークンの名前や種類を格納
Value トークンの実際の値を格納

どういうときにつかうのか?
パスワードリセット、メール確認、二要素認証、外部認証プロバイダー、リフレッシュトークン、カスタムトークンなどだそうです

AIの見解: OAuth 2.0のアクセストークンは通常200〜400文字程度
JWTベースのトークンは500〜1000文字程度になることがあります
リフレッシュトークンは通常、アクセストークンよりも長くなる傾向があります
トークンのサイズが将来的に大きくなる可能性を考慮する必要があります
よって2000文字程度の長さが妥当では?
とのこと。

AspNetUserRolesテーブル

AspNetUserRolesテーブルは、ユーザーとロールの関連付けに関する情報が格納

列名 nvarchar(max) 内容
UserId UserIdを設定
RoleId RoleIdを設定

AspNetRolesテーブル

AspNetRolesテーブルは、アプリケーション内のロールに関する情報が格納

列名 nvarchar(max) 内容
Id UserIdを設定
Name RoleIdを設定
NormalizedName 検索などの比較で効率的に行うための正規化(大文字)
ConcurrencyStamp 同時実行制御に使用。GUIDが使われる

・AIの見解
ConcurrencyStamp・・・同時実行制御に使用されるタイムスタンプです。通常GUIDが使用される。GUIDの文字列表現は通常36文字。よって36文字

AspNetRoleClaimsテーブル

AspNetRoleClaimsテーブルは、ロールに関連付けられた追加の情報(クレーム)が格納
AspNetUserClaimsのRole版

列名 nvarchar(max) 内容
Id プライマリキーとして機能する一意の識別子
RoleId クレームを設定するRoleId
ClaimType クレームの種類や名前
ClaimValue クレームの値

クレームは、ユーザーはロールといった概念のほかに情報を追加し細かい認証の制御を行うために使用する
よって、クレームの種類や値を設定するのは開発者次第のためお好きな文字数を設定すればよい
長い名称を使うことなければ64文字とかで十分かなと


同時実行制御について

同じレコードを複数のリクエストにより変更を行った際に、どちらのリクエストで変更したのか、判断するために、ConcurrencyStampにGUIDを設定し判断に使っています。

  1. Selectで対象のレコードの情報を取得する
  2. 新しいGUIDを取得する
  3. 対象レコードを取得する際に、1で取得したConcurrencyStampも条件に含めレコードをしぼり更新を行う。その際に新しいGUIDを設定する

これにより、同時実行した場合、更新ができれば自分のリクエストにより更新ができたことになり
更新ができない場合(他のリクエストによりすでにConcurrencyStampの値が変わっていた場合)は更新が失敗することになります

投稿日時: 2024-10-12 06:24:12
更新日時: 2024-10-12 12:13:12

内部リンク

最近の投稿

タグ

アーカイブ

その他