リダイレクト後にreturnurlにhttppost
-
05-10-2019 - |
質問
アイテムに入札する前にユーザーがログインする必要があるASP.NET MVC 2.0アプリケーションを書いています。 ActionFilterを使用して、ユーザーがログインしていることを確認し、そうでない場合はログインページに送信してReturn URLを設定しています。以下は、アクションフィルターで使用するコードです。
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Result = new RedirectResult(String.Concat("~/Account/LogOn","?ReturnUrl=",filterContext.HttpContext.Request.RawUrl));
return;
}
ログオンコントローラーでは、ユーザーの資格情報を検証してからサインインして、return URLにリダイレクトします
FormsAuth.SignIn(userName, rememberMe);
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
私の問題は、これは常にget(httpget)リクエストを使用するのに対し、私の元の提出物は投稿(httppost)であり、常に投稿でなければならないことです。正しいHTTPMethodが使用されることを確認するために、HTTPMethodまたは回避策を含むこのURLを渡す方法を提案できますか?
解決
これを行う簡単な方法はありません。私がお勧めするのは、一部のURLに投稿するときではなく、認証されたURLに投稿するフォームを要求するときに、認定されていないユーザーをログインページにリダイレクトすることです。
認証されていないユーザーに提示しているフォームがサイトの認証された部分に投稿することがわかっている場合は、フォームを提示しないでください。このフォームが要求された場合、認証のためにログインページにリダイレクトし、認証された後に元のフォームにリダイレクトします。これにより、認証されたユーザーのみが保護されたリソースに投稿するようにします。
自動化されたPOSTリクエストに関する限り(ボット、Webサービス、...)、単純な401ステータスコードをリクエストに戻すと、資格情報を提供しないリクエストは十分でなければなりません。
他のヒント
私はあなたが認証を入札したい理由を理解していると思います POST
アクション。入札にはログインが必要ですが、ユーザーにログされていない人は誰でもオークションページを見ることができます。 eBay/Amazonなどのように。ユーザーに基づいて支払いまたはアクションが必要になるまで、すべてが表示されます。
属性を変更して代わりに返すことができます Request.UrlReferrer
ログインページの場合 Request.RequestType
aです POST
. 。その後、オークションページにリダイレクトされ、ログインしたら再び入札をクリックできます。特定のフィールド、たとえば金額を渡すこともできます。 UrlReferrer
そのため、オークションページに着陸すると、フィールドの金額を再入力できます。そのフィールドをから得ることができます Request.Form
コレクション。
// in usage...
[RequireLogin(AdditionalFields="amount,someotherfield")]
[HttpPost]
public ActionResult Bid(.....)
// the attribute
class RequireLoginAttribute : ActionFilterAttribute
{
public string AdditionalFields { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
var returnUrl = filterContext.HttpContext.Request.RawUrl;
if (filterContext.HttpContext.Request.RequestType == "POST")
{
returnUrl = filterContext.HttpContext.Request.UrlReferrer.PathAndQuery;
// look for FORM values in request to append to the returnUrl
// this can be helpful for a good user experience (remembering checkboxes/text fields etc)
}
filterContext.Result = new RedirectResult(String.Concat("~/Account/LogOn", "?ReturnUrl=", returnUrl));
return;
}
base.OnActionExecuting(filterContext);
}
}
同じ名前の2つのコントローラーメソッドを記述できますが、1つはget用、もう1つはdempdata(またはセッション)のgetメソッドのreturnurlを覚えておいてください。
コードは次のようになるかもしれません:
public ActionResult LogOn(string returnUrl)
{
if (!string.IsNullOrEmpty(returnUrl))
{
TempData["ReturnUrl"] = returnUrl;
}
return View();
}
[HttpPost]
public ActionResult LogOn(LogOnModel model, FormCollection collecton)
{
if (ModelState.IsValid)
{
AuthenticationResult logonStatus = TransactionScriptFactory.GetTransactionScript<UserTransactionScripts>()
.LogOn(model.Email, model.Password);
if (logonStatus.AuthResult == AuthResultEnum.Success)
{
FormsService.SignIn(logonStatus.User.UserId, logonStatus.User.NickName, false);
object returnUrl = string.Empty;
TempData.TryGetValue("ReturnUrl", out returnUrl);
string returnUrlStr = returnUrl as string;
if (!string.IsNullOrEmpty(returnUrlStr))
{
return Redirect(returnUrlStr);
}
else
{
return RedirectToAction("Index", "Home");
}
}
......
Get Actionを使用して最初にページに到着し、データをサーバーに投稿することで最初に到着したときです。
request.urlreferrerからURL全体を取得できると思います。