ASP.NETでDetails時にログイン中ユーザーのデータのみ出力する方法

この記事は約 4 分で読めます。

前提となるModelの構造

TodoMODELの構造

    public class Todo
    {
        public int Id { get; set; }
        public string Sammary { get; set; }
        public string Detail { get; set; }
        public DateTime Limit { get; set; }
        public bool Done { get; set; }

        public virtual User User { get; set; }
    }

TodoModelには、IDがあります。

また概要と詳細があり、期限と完了フラグがあります。

UserModelの構造

    public class User
    {
        public int id { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
        public virtual ICollection<Todo> todoes { get; set; }
    }

こちらもシンプルにUserIDとNameとPassword。そして、Todoを複数持っているといった感じですね。

Detailsでログイン中ユーザーの情報を取ってみる!

ここでは、スキャフォールドで作成してくれるDetailsをみていきます!

        // GET: Todoes/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Todo todo = GetLoginUser().Todoes.FirstOrDefault(c => c.Id == id);
            if (todo == null)
            {
                return HttpNotFound();
            }
            return View(todo);
        }

基本的にはスキャフォールドすると上記のようにidを引数にしてますね!

idがnullだったら、バッドリクエストを返します。

この箇所は私が書いた箇所です。

Todo todo = GetLoginUser().Todoes.FirstOrDefault(c => c.Id == id);

GetLoginUser()の中身は下記のようになっています。

        private User GetLoginUser()
        {
            return db.Users.FirstOrDefault(u => u.UserName == User.Identity.Name);
        }

単純にログインユーザーをユーザーテーブルから取得するッといった感じですね。

さっきのコードと合わせてみてみると下記のようになります。

var User = db.Users.FirstOrDefault(u => u.UserName == User.Identity.Name);
Todo todo = User.Todoes.FirstOrDefault(c => c.Id == id);

DBからユーザー情報を取得し、そのユーザーのに紐づいているTodoの中から引数にあるidのTodoを引っ張ってきているといった感じですね!

Detailsでもログイン中ユーザーの情報を取得する必要がある?

ここで疑問になるのが、Detailsはidを引数に、Todoを探して表示するといった挙動なのに、わざわざユーザーを絞って表示する必要があるのか?

という点です。

Indexは全情報を表示するので、その中からログインユーザーの情報のみというのはわかる話ですが、Detailsの場合idを直接していするのに必要?ってなりますよね。

はい。必要です。

例えば、URL直打ちされた場合はどうなるのでしょう?

今回TodoesController全体にAuthorizeアノテーションを付けてるので、ログインしている状態でしか情報が見れません。

ですが、スキャフォールドで作成したまんまで使うと、ログインしていれば誰でも情報は見れるようになります。

例えば下記のような場合。

  • a => idが1,2のレコードを保持
  • b => idが3,4のレコードを保持

こうなっていた場合、Detailsのパスは下記のようになります。

  • http://localhost/プロジェクト名/Todo/Details/1~4のid

aさんがログインした状態で、Url直打ちで3 or 4 のidを入れたとすると?

ログインユーザーの情報のみに絞っていないと、見ることができます。

これは大問題!

ということで、Detailsでも忘れずにログインユーザーの情報のみに絞るということを忘れないようにしましょう。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA