1

I'm trying to do something like the following: jQuery Part:

function ajaxLogin() {
    $.ajax({
         url: "auth/credentials",
         type: "POST",
         data: { UserName: $("#form_username").val(), Password: $("#form_pwd").val() },
         success: function (data) {
             $("#login_div").hide();
         },
         error: function (jqXHR,textStatus,errorThrown) {
             $("$login_msg").text(errorThrown);
         }
    });
}

However, for some reason it's always coming back to the success function and data contains the html contents of the current html document.

My ServiceStack AuthProvider contains the following TryAuthenticate:

public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
    {
        var session = authService.GetSession();
        string error = null;
        try
        {
            var dataSource = authService.TryResolve<RiskViewDataSource>();
            var diModelInstance = dataSource.diModelRootObject;
            string authResult = UserFactory.authenticate(session.Id, userName, password, false);
            if ("OK".Equals(authResult))
            {
                session.IsAuthenticated = true;
                session.UserName = session.DisplayName = userName;
                session.UserAuthId = password;
                UsersManager.generateUsersPolicies();
                UsersManager.loadUserPolicies();
                return true;
            }
            else
            {
                session.IsAuthenticated = false;
                session.UserName = session.DisplayName = null;
                session.UserAuthId = null;
                authService.RemoveSession();
                return false;
            }
        }
        catch (Exception e)
        {
            Log.Error(e.ToString());
            session.IsAuthenticated = false;
            session.UserName = session.DisplayName = null;
            session.UserAuthId = null;
            error = "Could not connect to RiskView database";
        }

        if (error != null)
        {
            throw HttpError.Unauthorized(error);
        }
        else
        {
            return false;
        }
    }
2
  • Are you sure TryAuthenticate gets called? Commented Jul 16, 2013 at 7:17
  • Yep, it definitely gets called. I can step through the call to TryAuthenticate and even if it Throws the Http.Unauthorized(error), the ajax call is still getting the contents of index.html. The index.html contains my page with the ajax call. I can't figure out why though. Commented Jul 17, 2013 at 0:58

1 Answer 1

1

Ok, after a day of messing about I've come up with this solution which works for me. I had to create a new service request for logging in. I called it RenewSession.

Service Stack Part:

[Route("/RenewSession", "POST")]
public class RenewSessionRequest : IReturn<RenewSessionResponse>
{
}

public class RenewSessionResponse : IHasResponseStatus
{
    public RiskViewJsonObject Result { get; set; }
    public ResponseStatus ResponseStatus { get; set; }
}

public class RenewSessionService : Service, IPost<RenewSessionRequest>
{
    public object Post(RenewSessionRequest request)
    {
        string username = this.Request.GetParam("UserName");
        string password = this.Request.GetParam("Password");
        string message = "";

        IAuthProvider authService = AuthService.GetAuthProvider("credentials");
        Boolean success = false;
        try
        {
            var response = authService.Authenticate(this, this.GetSession(), new Auth { UserName = username, Continue = null, Password = password });
            success = true;
        }
        catch (Exception e)
        {
            message = e.ToResponseStatus().Message;
        }

        return new RenewSessionResponse { Result = new Mapping.RiskViewJsonObject("{ \"success\" : " + (success ? "true" : "false") + ", \"message\" : \"" + RiskViewJsonObject.cleanForJSON(message)+ "\" }") };
    }
}

Html and Ajax Part:

1) Add a div to the page for the login details (Hide it to start with)

<div id="login-div" style="position:absolute;display:hidden;left:100;top:100;background-image:url('images/login_bk.png');">
    <p id="login_error_msg"></p>
    <form id="login_form" onsubmit="loginSubmit(); return false;">
        <table>
            <tr>
                <td>Username:<input id="in_un" type="text" name="UserName" autocomplete="off" autocorrect="off" autocapitalize="off"/></td>
            </tr>
            <tr>
                <td>Password:<input id="in_pw" type="password" name="Password" autocomplete="off" autocorrect="off" autocapitalize="off"/></td>
            </tr>
            <tr>
                <td style="text-align: center;">
                    <input id="login_submit" type="submit" class="hand_cursor" value="Login">
                </td>
            </tr>
        </table>
    </form>
</div>

2) I add 401 checks to every ajax query on my page (401 tells us that the session has expired)

$.getJSON('/Menus?format=json', function(data) {
    // Do some stuff
}).fail(function (jqxhr,textStatus,error) {
    if (jqxhr.status == 401) {
        loginAgain();
    }
});

3) Show the div to re-login

function loginAgain(reloadMenu) {
    $("#login-div").show("slow");
}

4) The onclick for login button or onsubmit event for the login form

    function loginSubmit() {
        if ($("#in_un").val().trim() == "" || $("#in_pw").val().trim() == "") {
            $("#login_error_msg").text("Username or Password is still empty.");
            return false;   // Prevent form from submitting
        } else {
            $("#login_submit_btn").attr("disabled","disabled");
            $("#login_error_msg").text("");
            $.ajax({
                url: "/RenewSession?format=json",
                type: "POST",
                data: { UserName: $("#in_un").val(), Password: $("#in_pw").val() },
                success: function (data, textStatus, jqXHR) {
                    $("#login_submit_btn").removeAttr("disabled");
                    if (data.Result.success) {
                        $("#login-div").hide();
                    } else {
                        if (data.Result.message) {
                            $("#login_error_msg").text(data.Result.message);
                        } else {
                            $("#login_error_msg").text(textStatus);
                        }
                        $("#in_pw").focus();
                    }
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    $("#login_submit_btn").removeAttr("disabled");
                    $("#login_error_msg").text("ERROR: "+errorThrown);
                    $("#in_pw").focus();
                }
            });
        }
        return false;   // Stop the form submiting, we're just gonna hide the div
    }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.