0

FormsAuthentication.RedirectFromLoginPage呼び出したときと、呼び出しResponse.Redirect(FormsAuthentication.GetRedirectUrl())て手動でリダイレクトしたときのプログラムの動作の違いを理解したいです。

以下のコメントをご覧ください。

LoginController/Index(2 つのアクション、1 つは 用、HttpGetもう 1 つは 用HttpPost) があります。このコントローラーのビューは、アプリケーションのログイン ページを表します。

また、ホームページまたはランディング ページ、つまり、ユーザーがログインに成功した後に移動する必要があるページもあります。これは、私のアプリケーションではHomeController's Indexアクションと~Views/Home/Index.cshtmlビューによって表されます。

3つのシナリオを提示しました。私はシナリオ 1 を理解しており、そのように機能することを期待していますが、シナリオ 2 と 3 の違いに気付きました。

シナリオ 1

namespace Controllers
{
    [AllowAnonymous]
    public class LoginController : Controller
    {
        [HttpPost]
        public ActionResult Index(Login loginViewModel)
        {
            if (ModelState.IsValid)
            {
                var user = ValidateUser(loginViewModel);

                if (user != null)
                {
                    // Other stuff: set cookies, session state, etc.

                    return RedirectToAction("Index", "Home");
                }
                else
                {
                    ModelState.AddModelError("", "Invalid password. Please try again.");
                }
            }

            // If the user was a valid user, the flow-of-control won't reach here
            // as expected and the user will be taken to the view that is served
            // by the HomeController::Index() action. If it is by convention, it will 
            // be the ~Views/Home/Index.cshtml view. This is fine.
            return View();
        }
    }
}

シナリオ 2

namespace Controllers
{
    [AllowAnonymous]
    public class LoginController : Controller
    {
        [HttpPost]
        public ActionResult Index(Login loginViewModel)
        {
            if (ModelState.IsValid)
            {
                var user = ValidateUser(loginViewModel);

                if (user != null)
                {
                    // Other stuff: set cookies, session state, etc.

                    Response.Redirect(FormsAuthentication.GetRedirectUrl(loginViewModel.UserName, 
                        loginViewModel.RememberMe));
                }
                else
                {
                    ModelState.AddModelError("", "Invalid password. Please try again.");
                }
            }

            // If the user was a valid user, the flow-of-control still reaches here
            // as expected. And as expected, it renders the same View, i.e. the View
            // associated with the controller we are in, which is ~Views/Login/Index, 
            // which represents the login page. This is wrong. I shouldn't redirect here.
            // I understand this. My question here is two fold:
            // 1) I am simply trying to understand the difference in behaviors of the three 
            //    scenarios described in this question.
            // 2) Given this, the right way would be to not use Response.Redirect here but instead
            //    use RedirectToAction. However, if I wanted to use Response.Redirect, what should
            //    I do?
            return View();
        }
    }
}

シナリオ 3

namespace Controllers
{
    [AllowAnonymous]
    public class LoginController : Controller
    {
        [HttpPost]
        public ActionResult Index(Login loginViewModel)
        {
            if (ModelState.IsValid)
            {
                var user = ValidateUser(loginViewModel);

                if (user != null)
                {
                    // Other stuff: set cookies, session state, etc.

                    FormsAuthentication.RedirectFromLoginPage(loginViewModel.UserName, 
                        loginViewModel.RememberMe);
                }
                else
                {
                    ModelState.AddModelError("", "Invalid password. Please try again.");
                }
            }

            // If the user was a valid user, the flow-of-control still reaches here
            // as expected. However, magically, somehow, even though the statement below
            // suggests that the user must be taken to the View of the same controller and
            // action that we are currently in, i.e. the View of the LoginController::Index()
            // action, i.e. the ~Views/Login/Index.cshtml, it magically takes me to the 
            // ~Views/Home/Index.cshtml instead, which is what is specified as the LoginPage
            // attribute of the <authentication>/<forms> element in the web.config.
            // I want to know how this happens.
            return View();
        }
    }
}

アップデート

私は今、途方に暮れています。現在、使用しているシナリオ 1でさえ、クラスでアクションをRedirectToAction呼び出しています。Index()LoginController

4

2 に答える 2

1

実際の違いは、 FormsAuthentication.RedirectFromLoginPage() は Cookie を設定してからリダイレクトを行いますが、 FormsAuthentication.GetRedirectUrl() はリダイレクト URL のみを返すことです。

面白いことに、 FormsAuthentication.GetRedirectUrl() の実装は次のようになります。

public static String GetRedirectUrl(String userName, bool createPersistentCookie)
{ 
    if (userName == null) 
        return null;
    return GetReturnUrl(true); 
}

したがって、実際には userName および createPersistentCookie パラメータは完全に無視されます。GetRedirectUrl を呼び出す前に、FormsAuthentication.SetAuthCookie( userName, true/false ) を手動で呼び出す必要があります。

于 2013-01-07T09:03:51.133 に答える
0

Vasilyに同意します。 認証チケットを発行し、メソッドRedirectFromLoginPageを使用してデフォルトのCookieに配置します。この動作については、ここで 読むことができます。SetAuthCookie

Cookieの作成をより適切に制御したい場合(暗号化、有効期限、プリンシパルの拡張)、Cookieを自分で作成する必要があります。ここここで
プロセス全体を説明しました。

于 2013-01-07T09:17:31.233 に答える