问题
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;
}
}
回答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
}
来源:https://stackoverflow.com/questions/17669389/how-can-i-authenticate-with-servicestack-using-jquery-ajax