Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • André Lange 108 posts 410 karma points
    Nov 21, 2018 @ 18:30
    André Lange
    0

    Login to member area, returnUrl

    Hi, i am trying to setup a returnUrl for my project, so i can link to pages inside the protected area.

    For some reason i keep getting /umbraco/RenderMvc as the return url...

    I get correctly redirected to the login page if i am not logged in. But after i login it doesn't redirect me properly..

    I am unable to get it to work... Hope someone can see what is going wrong.

    My code:

    LoginSurface Controller:

      public ActionResult RenderLogin(string ReturnUrl)
        {
            var model = new LoginModel();
    
            model.ReturnUrl = ReturnUrl;
    
            return PartialView("_Login", model);
        }
        //https://our.umbraco.com/Documentation/Reference/Querying/MemberShipHelper/
        // GET: LoginSurface
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult SubmitLogin(LoginModel model)
        {
            var currentPageId = UmbracoContext.Current.PageId;
            var currentPage = Umbraco.TypedContent(currentPageId);
            var loginUrl = currentPage.Url; 
            if (ModelState.IsValid)
            {
                var membershipHelper = new UmbracoHelper(UmbracoContext.Current).MembershipHelper;
    
                if (membershipHelper.Login(model.Email, model.Password))
                {
                    FormsAuthentication.SetAuthCookie(model.Email, model.PersistantCookie);
                    UrlHelper myHelper = new UrlHelper(HttpContext.Request.RequestContext);
    
                    if (model.ReturnUrl != loginUrl)
                    {
                        if (model.ReturnUrl != string.Empty && model.ReturnUrl != null)
                        {
                            return this.Redirect(model.ReturnUrl);
                        }
                    }
                    var urlTarget = CurrentPage.GetPropertyValue<IEnumerable<IPublishedContent>>("successfulLoginDestination");
    
                    return RedirectToUmbracoPage(urlTarget.First().Id);
                }
            }
            else
            {
                ModelState.AddModelError("", "The username or password provided is incorrect.");
            }
            return CurrentUmbracoPage();
        }
    

    My login controller

    // GET: Login
            public ActionResult Index(Login currentPage)
            {
                var model = new LoginViewModel();
                var member = Umbraco.MembershipHelper.GetCurrentMemberProfileModel();
    
                if (member != null)
                {   // member is logged in.
                    var urlTarget = CurrentPage.GetPropertyValue<IEnumerable<IPublishedContent>>("successfulLoginDestination");
                    return this.Redirect(urlTarget.First().Url);
                }
    
    
                return View(model);
            }
    

    My login form:

    @model Website.Models.Helpers.LoginModel
    
    @using (Html.BeginUmbracoForm("SubmitLogin", "LoginSurface", System.Web.Mvc.FormMethod.Post))
    {
        @Html.AntiForgeryToken()
        <div class="form-group mb-3">
            <div class="input-group input-group-alternative">
                <div class="input-group-prepend">
                    <span class="input-group-text"><i class="fas fa-at"></i></span>
                </div>
                @Html.TextBoxFor(m => m.Email, new { @class = "form-control", @placeholder = "Email" })
            </div>
        </div>
        <div class="form-group">
            <div class="input-group input-group-alternative">
                <div class="input-group-prepend">
                    <span class="input-group-text"><i class="fas fa-key"></i></span>
                </div>
                @Html.PasswordFor(m => m.Password, new { @class = "form-control", @type = "password", @placeholder = "Password" })
            </div>
        </div>
        <div class="form-group">
            <div class="custom-control custom-control-alternative custom-checkbox">
                @Html.CheckBoxFor(m => m.PersistantCookie, new { @id = "PersistantCookie", @class = "custom-control-input" })
                @Html.LabelFor(m => m.PersistantCookie, new { @id = "PersistantCookieLabel", @class = "custom-control-label" })
            </div>
        </div>
        <div class="form-group">
            <div class="input-group input-group-alternative">
                <div class="input-group-prepend">
                    <span class="input-group-text"><i class="fas fa-eye-slash"></i></span>
                </div>
                @Html.HiddenFor(x=> x.ReturnUrl, new { @Value=Model.ReturnUrl})
                <p class="form-control">@Model.ReturnUrl</p>
            </div>
        </div>
    
        @Html.ValidationSummary()
        <div class="text-center">
            <button type="submit" class="btn btn-primary my-4">Sign in</button>
        </div>
    } 
    

    Login Page

    @model Website.Models.LoginViewModel
    @{ 
        var returnUrl = Request.Url.PathAndQuery;
    
    }
    <section class="section section-shaped section-lg pt-lg-0 mt--200">
        <div class="container pt-lg-md">
            <div class="row justify-content-center">
                <div class="col-lg-5">
                    <div class="card bg-secondary shadow border-0">
                        <div class="card-header bg-white pb-5">
                            <h1 class="text-center mb-3">Log ind</h1>
                            <div class="text-muted text-center mb-3">
                                <p>Hvis du ikke er medlem, eller har problemer med login.</p>
                                <p>Så tag kontakt via kontakt siden.</p>
                            </div>
                        </div>
                        <div class="card-body px-lg-5 py-lg-5">
                            <div class="text-center text-muted mb-4">
                                <small>Ellers log ind her</small>
                            </div>
                            @{ Html.RenderAction("RenderLogin", "LoginSurface", new { ReturnUrl = returnUrl }); }
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>
    
  • Marc Goodson 2141 posts 14344 karma points MVP 8x c-trib
    Nov 21, 2018 @ 23:29
    Marc Goodson
    0

    Hi Andre

    Your picker for successfulLoginDestination is it configured to only be a single picker? eg editors can only pick one item?

    if so then my guess is the Property Value Converter will return an IPublishedContent item instead of an IEnumerable

    So would changing to:

    var urlTarget = CurrentPage.GetPropertyValue<IPublishedContent>("successfulLoginDestination");
    

    and

    return RedirectToUmbracoPage(urlTarget.Id);
    

    make a difference?

    regards

    Marc

  • André Lange 108 posts 410 karma points
    Nov 22, 2018 @ 07:32
    André Lange
    0

    Yes it will only pick a single item. But that part works correctly.

    It is the return url part that doesn't work.

  • Marc Goodson 2141 posts 14344 karma points MVP 8x c-trib
    Nov 22, 2018 @ 09:02
    Marc Goodson
    0

    Hi André

    Cool, so what is the value of the return url in the following places:

    SurfaceController - RenderLogin

    model.ReturnUrl = ReturnUrl;
    

    and

    SurfaceController - SubmitLogin

    model.ReturnUrl
    

    and in your LoginForm

    <p class="form-control">@Model.ReturnUrl</p>
    

    and LoginPage

    var returnUrl = Request.Url.PathAndQuery;
    

    I'm not sure I can see where returnUrl gets set to be the url of the page the person was trying to visit when they were redirected to the login page?

    Would suggest setting a breakpoint and stepping through the code, and seeing what returnUrl is at all of the above points, to see where it is going awry and whether this line ever gets executed:

       return this.Redirect(model.ReturnUrl);
    

    regards

    Marc

  • André Lange 108 posts 410 karma points
    Nov 22, 2018 @ 10:39
    André Lange
    0

    It first gets set here:

    On loginPage    var returnUrl = Request.Url.PathAndQuery; 
    

    Then it is used in the partialview, where i render the login form:

    @{ Html.RenderAction("RenderLogin", "LoginSurface", new { ReturnUrl = returnUrl }); }
    

    From there i set it in the model, in the surface controller, here:

    public ActionResult RenderLogin(string ReturnUrl)
        {
            var model = new LoginModel();
    
            model.ReturnUrl = ReturnUrl;
    
            return PartialView("_Login", model);
        }
    

    That renders the login partial view, with the returnUrl in the model. Then i set it on the page here in the loginform partialview:

    @Html.HiddenFor(x=> x.ReturnUrl, new { @Value=Model.ReturnUrl})
    

    And then submitting the form to the surfacecontroller, where i take that value with me.

  • Marc Goodson 2141 posts 14344 karma points MVP 8x c-trib
    Nov 22, 2018 @ 12:03
    Marc Goodson
    0

    Apologies, what I mean, just because it's hard to imagine, is whether loginPage is a special page for logging in on, eg /login, in which case your returnUrl will always be the same... or if by 'loginPage' you mean the content page you are currently on, that happens to contain the login form?

    If you set a breakpoint, and step through the code during the login process, you can see how it is passed along at each stage, to the final return 'redirect' to get a clue as to where it is going awry.

    eg what is the value of

    var returnUrl = Request.Url.PathAndQuery;

    if that is incorrect, then it will be passed incorrectly all the way through!...

    PathAndQuery will return the page and any querystring:

    https://docs.microsoft.com/en-us/dotnet/api/system.uri.pathandquery?view=netframework-4.7.2#SystemUriPathAndQuery

    If you have a separate Login page, that the user is redirected to, then this might be

    var returnUrl = "/login?returnUrl=/some-page/behind-login;

    So I'd expect you to read the 'returnUrl' part? rather than include the login path?

    (but I'm just speculating!)

    If you set the breakpoint and examine the value of the returnurl at each part of the process, that should hopefully indicate where it is going wrong!

    eg in the hidden field, or after it is posted back and 'bound' to the loginviewmodel.

  • André Lange 108 posts 410 karma points
    Nov 22, 2018 @ 12:08
    André Lange
    0

    It is a separate login page, you end up at if you try to access a restricted page.

    I have only restricted access through Umbraco CMS, on the specific pages.

    I am not getting a ?returnUrl = something It just displays the full page i would want to get to, only it is on the login page.

    So i try to access /member/news/some-news-article Since im not logged in, it jumps to the login page, but the url is still /member/news/some-news-article.

    I have tried setting break points and going through it. Between clicking login and landing on the loginsurface controller, the value just changes...

  • Marc Goodson 2141 posts 14344 karma points MVP 8x c-trib
    Nov 22, 2018 @ 12:11
    Marc Goodson
    100

    so in your step through in the first bit is...

    var returnUrl = Request.Url.PathAndQuery;

    set to "/member/news/some-news-article"

    or 'something else' ?

    Also in your form partial you have

    @Html.HiddenFor(x=> x.ReturnUrl, new { @Value=Model.ReturnUrl})

    but I think you already set the ReturnUrl in the model, before rendering the Partial, therefore would

    @Html.HiddenFor(x=> x.ReturnUrl)

    maintain the same value?

  • André Lange 108 posts 410 karma points
    Nov 22, 2018 @ 12:18
    André Lange
    0

    Yes setting it to just @Html.HiddenFor(x=> x.ReturnUrl) Gives the same value. I thought i had to set it ^^

  • Marc Goodson 2141 posts 14344 karma points MVP 8x c-trib
    Nov 22, 2018 @ 12:28
    Marc Goodson
    0

    So it works... ?

  • André Lange 108 posts 410 karma points
    Nov 22, 2018 @ 13:11
    André Lange
    0

    Sorry for the wait, yes. for some reason that seems to work... I do not understand why it would change the value, but changing that seems to have made it work...

Please Sign in or register to post replies

Write your reply to:

Draft