質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.59%

ASP.NET Identityでのログインをメールアドレスとユーザー名を同列にしない方法

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,335

pomu.pomupomu

score 18

 前提・実現したいこと

ASP.NET mvcにて掲示板を作成している初学者です。不束者ですがよろしくお願いします。
現在、ASP.NET Identityでのログイン方法をEmailアドレスで行いたいと思い投稿しました。
(最初からEmailアドレスでのログインにはなっていますが、DBにおけるAspNetUsersテーブル内のEmailのみならず、UserNameの項目にもEmailアドレスが書き込まれるため、「ようこそpochi@pochi.comさん」みたいにヘッダー部に表示されるため都合が悪いと考えました。)

 発生している問題・エラーメッセージ

ログインフォームにユーザー名とパスワードでログインすることはできるようになりましたが、Emailアドレスでログインすることができません。ユーザー名のモデル参照部分をmodel.Emailに差し替えましたが、次のように「無効なログイン試行です」という表示がされます。
イメージ説明

 試したこと

以下に記したコードのように試した結果、うまくいきませんでした。
安直ですが、「model.UserNameと記された箇所をmodel.Emailと修正し、Model定義については[EmailAddress]を挿入したらいいのではないか?」と考え実行しました。
(無知ゆえに自分のあずかり知らないページがあるかもしれません、その場合は申し訳ありませんが指摘してくだされば加筆します。)

以下にASP.NETで生成した部分でのログインにまつわり、編集した部分を記します。

AccountviewModel

    public class LoginViewModel
    {
        [Required]
        [EmailAddress]
        [Display(Name = "電子メール")]
        public string Email { get; set; }

        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "パスワード")]
        public string Password { get; set; }

        [Display(Name = "このアカウントを記憶する")]
        public bool RememberMe { get; set; }
    }

Login.cshtml

                  @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
                        {
                            @Html.AntiForgeryToken()
                            @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                            <dl>
                                <dt>電子メール</dt>
                                <dd>
                                    @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
                                    @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" })
                                </dd>
                                <dt class="text01">パスワード</dt>
                                <dd>
                                    @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
                                    @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })
                                </dd>
                            </dl>

                            <div class="form-group">
                                <div class="col-md-offset-2 col-md-10">
                                    <div class="checkbox">
                                        @Html.CheckBoxFor(m => m.RememberMe)
                                        @Html.LabelFor(m => m.RememberMe)
                                    </div>
                                </div>
                            </div>

                            <div class="form-group">
                                <div class="col-md-offset-2 col-md-10">
                                    <input type="submit" value="ログイン" class="btn btn-default" />
                                </div>
                            </div>
                        }

      AccountController.cs  

        //
        // POST: /Account/Login
        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }

            // これは、アカウント ロックアウトの基準となるログイン失敗回数を数えません。
            // パスワード入力失敗回数に基づいてアカウントがロックアウトされるように設定するには、shouldLockout: true に変更してください。
            var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
            switch (result)
            {
                case SignInStatus.Success:
                    return RedirectToLocal(returnUrl);
                case SignInStatus.LockedOut:
                    return View("Lockout");
                case SignInStatus.RequiresVerification:
                    return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
                case SignInStatus.Failure:
                default:
                    ModelState.AddModelError("", "無効なログイン試行です。");
                    return View(model);
            }
        }

                 

 補足情報  

   以上のことを試すに当たって、次のサイトを参考にしました。   (これを参考に、UserNameでのログインと、DBのAspNetUsersテーブルのUserNameにEmailアドレスではなくユーザー名の書き込みができるようになってから、安直なmodel等の編集を試みをしました)   Using User Name Instead of Email in ASP.NET Identity   https://www.codeproject.com/Articles/1052354/Using-User-Name-Instead-of-Email-in-ASP-NET-Identi     

 開発環境  

VS2017   Windows7   .Net Framework 4.6.1   MVC5

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

ログインフォームにユーザー名とパスワードでログインすることはできるようになりましたが、

参考にされている codeproject の記事のようにしたのですよね?

その記事は、たぶん(詳しくは読んでないので 100% の自信は無し)、Identity 2.0 で自動生成されるコードのデフォルトで Email とパスワードでログインする設定になるのを止めて、任意のユーザー名を UserName に設定して登録し、そのユーザー名とパスワードでログインできるように変更するというもののようです。

Emailアドレスでログインすることができません。

質問者さん自身が Email を使うのを止めて任意のユーザー名をログインに使うことに変更したのだから、それは当たり前かと思いますけど。

ログインはあくまで Identity 2.0 デフォルトの Email とパスワードで行い、Email とは別のハンドル名を「ようこそ〇〇〇さん」みたいにヘッダー部に表示したいということであれば、プロファイル情報として追加してはいかがですか?

具体的な方法は以下の記事を見てください。記事では FirstName, LastName, Birthday をプロファイル情報として追加していますが、同様な方法で HandleName を追加することを検討してみてください。

ASP.NET Identityのプロファイル情報のカスタマイズ
https://codezine.jp/article/detail/7845

追加したプロファイル情報の取得と表示は以下の記事が参考になると思います。ログイン後は表示の都度 DB にクエリを投げて情報を取得するような無駄なことは避けて、認証クッキーから取得するようにしています。

プロファイル情報を ClaimsIdentity へ追加
http://surferonwww.info/BlogEngine/post/2017/04/16/add-user-profile-information-to-claimsidentity.aspx

プロファイル情報を追加するのでなく、もともとある UserName を使うという方法もあるかもしれませんが、デフォルトで生成されるユーザー登録のアクションメソッドで、

var user = new ApplicationUser { UserName = model.Email, Email = model.Email };

と設定しているということは、UserName と Email を同じにするのは何か理由があるかもしれません。想像ですが、以下の記事にある「ASP.NET Identity 2.0 の新機能」とかに関係があるのかも。

「ASP.NET Identity入門」連載一覧
https://codezine.jp/article/corner/511

そのあたりがはっきりしない限りは(自分は調べてませんのではっきりしません)、プロファイル情報として追加するのが無難だと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/21 15:11

    プロファイル情報を用いて追加すれば良いこと、返事や記載されたリンク等を見た上で自分で試してみて「なるほど、これなら望んでいるものができる!」と理解しました。ありがとうございます。

    ただ、現在、作っていたソリュージョンのパッケージマネージャーコンソールについて、
    マイグレージョンを実行しようと試みましたがエラーが起き、解決策を提示していただいたのに解決しておらずに至らず申し訳ありません。近日中に理解し解決しようと考えております。

    キャンセル

  • 2018/08/21 16:21

    できました・・・。

    PM> Enable-Migrations -ContextTypeName Forum.Models.ApplicationDbContext -Force
    末尾に-Forceをつけることでマイグレーションできました。
    その後、指南通りに従い、メールアドレスでのログイン機能を維持したまま、アカウント登録時には
    (1)姓名 (2)ハンネ
    をIdentityで生成される項目の他に追加できました。

    ありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る