我如何与ServiceStack验证使用jQuery阿贾克斯ServiceStack、jQuery、阿贾克斯

2023-09-11 01:32:29 作者:小孩谈恋爱,大人别插嘴

我试图做类似如下: jQuery的部分:

 函数ajaxLogin(){
    $阿贾克斯({
         网址:认证/资格证书,
         键入:POST,
         数据:{用户名:$(#form_username)VAL(),密码:$(#form_pwd)VAL()},
         成功:功能(数据){
             $(#login_div)隐藏()。
         },
         错误:函数(jqXHR,textStatus,errorThrown){
             $($ login_msg)文本(errorThrown)。
         }
    });
}
 

然而,由于某种原因,它总是回来的成功的功能和数据包含当前的html文档的HTML内容。

我的ServiceStack AuthProvider包含以下TryAuthenticate:

 公众覆盖布尔TryAuthenticate(IServiceBase authService,用户名字符串,字符串密码)
    {
        VAR会话= authService.GetSession();
        字符串错误= NULL;
        尝试
        {
            VAR数据源= authService.TryResolve< RiskViewDataSource>();
            VAR diModelInstance = dataSource.diModelRootObject;
            字符串authResult = UserFactory.authenticate(session.Id,用户名,密码,假);
            如果(OK.Equals(authResult))
            {
                session.IsAuthenticated = TRUE;
                session.UserName = session.DisplayName =用户名;
                session.UserAuthId =密码;
                UsersManager.generateUsersPolicies();
                UsersManager.loadUserPolicies();
                返回true;
            }
            其他
            {
                session.IsAuthenticated = FALSE;
                session.UserName = session.DisplayName = NULL;
                session.UserAuthId = NULL;
                authService.RemoveSession();
                返回false;
            }
        }
        赶上(例外五)
        {
            Log.Error(e.ToString());
            session.IsAuthenticated = FALSE;
            session.UserName = session.DisplayName = NULL;
            session.UserAuthId = NULL;
            错误=无法连接到RiskView数据库;
        }

        如果(错误!= NULL)
        {
            抛出HttpError.Unauthorized(错误);
        }
        其他
        {
            返回false;
        }
    }
 

解决方案

好了,折腾了我想出了这个解决方案,为我工作了一天之后。我不得不创建一个新的服务请求进行登录。我把它叫做RenewSession。

服务栈部分:

  [路径(/ RenewSession,POST)
公共类RenewSessionRequest:IReturn< RenewSessionResponse>
{
}

公共类RenewSessionResponse:IHasResponseStatus
{
    公共RiskViewJsonObject结果{获得;组; }
    公共ResponseStatus ResponseStatus {获得;组; }
}

公共类RenewSessionService:服务,IPOST< RenewSessionRequest>
{
    公共对象后(RenewSessionRequest要求)
    {
        字符串的用户名= this.Request.GetParam(用户名);
        串密码= this.Request.GetParam(密码);
        字符串消息=;

        IAuthProvider authService = AuthService.GetAuthProvider(资格证书);
        布尔成功= FALSE;
        尝试
        {
            VAR响应= authService.Authenticate(这一点,this.GetSession(),新的身份验证{用户名=用户名,继续= NULL,密码=密码});
            成功= TRUE;
        }
        赶上(例外五)
        {
            。消息= e.ToResponseStatus()信息;
        }

        返回新RenewSessionResponse {结果=新Mapping.RiskViewJsonObject({\成功\:+(成功真:假)+\消息\:\+ RiskViewJsonObject.cleanForJSON(消息)+\})};
    }
}
 

HTML和Ajax部分:

1)添加一个div到页面的登录信息(隐藏它开始)

 < D​​IV ID =登录-DIV style="position:absolute;display:hidden;left:100;top:100;background-image:url('images/login_bk.png');">
    &其中,P的id =login_error_msg>&所述; / P>
    <形式ID =login_form的onsubmit =loginSubmit();返回false;>
        <表>
            &其中; TR>
                < TD>用户名:​​其中,输入ID =in_un类型=文本名称=用户名自动完成=关闭自动更正=关autocapitalize =关/>< / TD>
            < / TR>
            &其中; TR>
                < TD>密码:其中,输入ID =in_pw类型=密码NAME =密码自动完成=关闭自动更正=关autocapitalize =关/>< / TD>
            < / TR>
            &其中; TR>
                < TD风格=文本对齐:中心;>
                    <输入ID =login_submit类型=提交级=hand_cursor值=登陆>
                < / TD>
            < / TR>
        < /表>
    < /形式GT;
< / DIV>
 

2)我加401检查每一个AJAX查询我的网页上(401告诉我们,本次会议已过期)

  $。的getJSON('/菜单?格式= JSON',功能(数据){
    //做一些东西
}),失败(函数(jqxhr,textStatus,错误){
    如果(jqxhr.status == 401){
        loginAgain();
    }
});
 

3)显示DIV重新登录

 函数loginAgain(reloadMenu){
    $(#登录-DIV)显示(慢)。
}
 

4)的onclick的登录按钮或onsubmit事件的登录表单

 函数loginSubmit(){
        如果($(#in_un)。VAL()。修剪()==|| $(#in_pw)。VAL()。修剪()==){
            $(#login_error_msg)文本(用户名或密码仍然是空的。)。
            返回false; // prevent从提交表单
        } 其他 {
            $(#login_submit_btn)ATTR(已禁用,已禁用)。
            $(#login_error_msg)文本()。
            $阿贾克斯({
                网址:/ RenewSession格式= json的,
                键入:POST,
                数据:{用户名:$(#in_un)VAL(),密码:$(#in_pw)VAL()},
                成功:功能(数据,textStatus,jqXHR){
                    $(#login_submit_btn)removeAttr(禁用)。
                    如果(data.Result.success){
                        $(#登录-DIV)隐藏();
                    } 其他 {
                        如果(data.Result.message){
                            $(#login_error_msg)文本(data.Result.message)。
                        } 其他 {
                            $(#login_error_msg)文本(textStatus)。
                        }
                        $(#in_pw)专注()。
                    }
                },
                错误:函数(jqXHR,textStatus,errorThrown){
                    $(#login_submit_btn)removeAttr(禁用)。
                    $(#login_error_msg)文本(错误:+ errorThrown)。
                    $(#in_pw)专注()。
                }
            });
        }
        返回false; //停止形式submiting,我们只是要隐藏的div
    }
 

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;
        }
    }

解决方案

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
    }