CAS之5.2x版本之Ajax方式提交表单-yellowcong

本文介绍如何在CAS 5.2x版本中,通过Ajax方式提交表单进行单点登录。主要内容包括:知识准备、代码地址、表单提交返回状态分析、Ajax登录实现步骤、登录测试及原理(登录分析和返回值分析)。重点讨论了如何抓取所需参数,解析返回状态码以判断登录结果。
摘要由CSDN通过智能技术生成

cas单点登录,默认开发过程中,我们都是使用的是表单提交的方式,来完成和cas的数据库验证,这个案例中,我添加了验证码,如果输入三次不对,下次就得输入验证码了,这一篇,不是主要将验证码,主要讲的是,通过ajax请求的方式,来提交表单到服务器端,然后再返回到需要返回的站点。实现步骤:1、抓包,查看传递到cas服务器端,所需要的参数,2、获取返回的数据状态码表,来判断表单提交的结果。

知识准备

1、CAS之5.2x版本登录验证码-yellowcong

2、CAS之5.2x版本自定义登录页面-yellowcong

代码地址

https://gitee.com/yellowcong/springboot_cas/tree/master/cas-server-ajax

目录结构

这里写图片描述

架构

端口说明
https:yellowcong.com:9000cas服务端
http:yellowcong.com:8000客户端

表单提交返回的状态吗

代码意义
200可能是用户密码为空的情况
302登录成功
401用户密码不正确

ajax方式提交表单

界面casLoginView.html

这个是自定义登录界面,主要的操作,就是绑定登录按钮和验证码的操作。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <title th:text="${#themes.code('yellowcong.pageTitle')}"></title>
    <link rel="stylesheet" th:href="@{${#themes.code('yellowcong.css.file')}}"/>
    <script type="text/javascript" th:src="@{/themes/yellowcong/js/jquery-1.7.1.js}" ></script>
    <script type="text/javascript" th:src="@{/themes/yellowcong/js/code.js}" ></script>

</head>

<body>
<h1 th:text="${#themes.code('yellowcong.pageTitle')}"></h1>
<h2>yellowcong的登录模板</h2>
<div>
    <form method="post" th:object="${credential}">
        <!-- 用于判断验证码是否正确的情况 -->
        <input type="hidden" id="codeValid" value="false"/>
        <!-- 登录失败的次数,失败三次,就需要输入验证码了 -->
        <input type="hidden" id="loginCnt" value="0"/>

        <div id="info"></div>
        <div id="errors" th:if="${#fields.hasErrors('*')}">
            <span th:each="err : ${#fields.errors('*')}" th:utext="${err}"/>
        </div>
        <h2 th:utext="#{screen.welcome.instructions}"></h2>

        <section class="row">
            <label for="username" th:utext="#{screen.welcome.label.netid}"/>
            <div th:unless="${openIdLocalId}">
                <input class="required"
                       id="username"
                       size="25"
                       tabindex="1"
                       type="text"
                       th:disabled="${guaEnabled}"
                       th:field="*{username}"
                       th:accesskey="#{screen.welcome.label.netid.accesskey}"
                       autocomplete="off"/>
            </div>
        </section>

        <section class="row">
            <label for="password" th:utext="#{screen.welcome.label.password}"/>
            <div>
                <input class="required"
                       type="password"
                       id="password"
                       size="25"
                       tabindex="2"
                       th:accesskey="#{screen.welcome.label.password.accesskey}"
                       th:field="*{password}"
                       autocomplete="off"/>
            </div>
        </section>
        <!-- 验证码信息 -->
        <section id="captcha_sec"  style="display: none;">
            <img id="captcha_img" th:src="@{/captcha}" onclick="changeCode()" style="width: 125px;"/>
            <input type="text" id="code"/>
            <span id="code_str"></span>
        </section>
        <section>
            <input type="hidden" name="execution" th:value="${flowExecutionKey}"/>
            <input type="hidden" name="_eventId" value="submit"/>
            <input type="hidden" name="geolocation"/>
            <input class="btn btn-submit btn-block"
                   name="submit"
                   accesskey="l"
                   th:value="#{screen.welcome.button.login}"
                   tabindex="6"
                   type="submit" hidden="true"/>

            <!-- 定义一个自己的按钮 -->
            <input type="button" value="登录" id="btn_login" onclick="login()" class="btn_login"/>

        </section>
    </form>
</div>
</body>
</html>

ajax代码(code.js)

这个里面的东西,就是一堆的验证操作和业务逻辑,可以按照里面自己的需求来
核心代码

//发送请求到服务器
function postData(){
    var result = false;
    //发送请求到后台
    $.ajax({  
              type : "post",  // 使用提交的方法 post、get
              url : contextPath()+"/login",   // 提交的地址
              data : { 
                 username:$("input[name='username']").val(),
                 password:$("input[name='password']").val(),
                 execution:$("input[name='execution']").val(),
                 _eventId:"submit",
                 geolocation:"",
                 submit:"登录"
              },  // 数据
              async : false,   // 配置是否异步操作
              success : function(data, textStatus,xhr){  // 回调操作
                  //用户名和密码不能为空的情况错误
                  var msg = $(data).find("#errors").find("span").html();
                  setCodeInfo("info",true,msg);
                  console.log("登录失败");
              },  error: function(xhr, textStatus, errorMsg){
                    switch(xhr.status){
                    case 302:
                        var tagetUrl = getTargetPath();
                        //用命名活密码没有填写的情况
                        setCodeInfo("info",true,"登录成功,马上条撞到目标网站:"+tagetUrl);

                        //只有这个地方,才是登录成功的。
                        result = true;
                        //跳转服务
                        window.location.href=tagetUrl;
                        break;
                    case 401:
                        //验证失败的情况
                        setCodeInfo("info",true,"用户名和密码有问题");
                        break;  
                    }
              }
    });
     return result;
}

完整js代码

$(function(){
    // 验证码验证
    $("#code").blur(function(){
        var codeStr = $("#code").val();

        if(codeIsError()){
            console.log("验证失败");
            $("#codeValid").val("false");
        }else{
            //验证码设定为 false
            $("#codeValid").val("true");
            console.log("验证成功");
        }
    });

    //默认开始禁用按钮的
//  disable("btn_login",true);
});

//验证数据是否正确
function checkData(){

    //验证码检查
    if( $("#captcha_sec").attr("style").indexOf("block") > -1 && $("#codeValid").val() == "false"){
        setCodeInfo("info",true,"验证码有问题");
        return false;
    }

    //用户名检查
    var username = $("input[name='username']").val();
    var password = $("input[name='password']").val();
    if(stringIsEmpty(username) ){
        setCodeInfo("info",true,"用户不能为空");
        return false;
    }
    if(stringIsEmpty(password)){
        setCodeInfo("info",true,"密码不能为空");
    }

    return true;
}
//判断字符串是否为空
function stringIsEmpty(val){
    if(val == undefined || val == null || val.replace(/(^\s*)|(\s*$)/g, "") == ""){
        return true;
    }
    return false;
}
//登录到服务器
function login(){
    //更新登录次数
    updateLoginCnt();

    //判断按钮是否可用
    /*if(isDisable("btn_login")){
        return false;
    }*/

    if(!checkData()){
        return false;
    }

    //发送数据到服务器
    var loginSuccess = postData();
    //更新登录条数
    updateLoginCnt(loginSuccess);

}
//更新登录失败的次数
function updateLoginCnt(loginSuccess){
    //密码登录失败次数
    var loginCnt = Number($("#loginCnt").val());

    //当大于等于3次的时候,显示密码
    if(loginCnt >=3 && !loginSuccess){
        $("#captcha_sec").css("display","block");
    }

    //最后增加登录次数
    $("#loginCnt").val(loginCnt+1);
}
//按钮不可使用
function disable(elementId, isDisabled){
    if(isDisabled){
        //添加样式
        $("#"+id).addClass("btn_disable");
    }else{
        //移除样式
        $("#"+id).removeClass()("btn_disable");
    }
}
//判断按钮是否可用
function isDisable(elementId){
    var cls = $("#"+elementId).attr("class");
    if(cls.indexOf("btn_disable") > -1){
        return true;
    }else{
        return false;
    }
}
//获取目标站点的地址
function getTargetPath(){
    var url = window.location.href;
    //解码url
    return unescape(url.substr(url.indexOf("service=")+8));
}
//发送请求到服务器
function postData(){
    var result = false;
    //发送请求到后台
    $.ajax({  
              type : "post",  // 使用提交的方法 post、get
              url : contextPath()+"/login",   // 提交的地址
              data : { 
                 username:$("input[name='username']").val(),
                 password:$("input[name='password']").val(),
                 execution:$("input[name='execution']").val(),
                 _eventId:"submit",
                 geolocation:"",
                 submit:"登录"
              },  // 数据
              async : false,   // 配置是否异步操作
              success : function(data, textStatus,xhr){  // 回调操作
                  //用户名和密码不能为空的情况错误
                  var msg = $(data).find("#errors").find("span").html();
                  setCodeInfo("info",true,msg);
                  console.log("登录失败");
              },  error: function(xhr, textStatus, errorMsg){
                    switch(xhr.status){
                    case 302:
                        var tagetUrl = getTargetPath();
                        //用命名活密码没有填写的情况
                        setCodeInfo("info",true,"登录成功,马上条撞到目标网站:"+tagetUrl);

                        //只有这个地方,才是登录成功的。
                        result = true;
                        //跳转服务
                        window.location.href=tagetUrl;
                        break;
                    case 401:
                        //验证失败的情况
                        setCodeInfo("info",true,"用户名和密码有问题");
                        break;  
                    }
              }
    });
     return result;
}
//---------------------------------------------------------------------
//显示消息用
//---------------------------------------------------------------------
function showMessage(code,data){
    var msg = $(data).find("#errors").find("span").html();
    switch(code){
    case 200:
        //用命名活密码没有填写的情况
        console.log(msg);
        break;
    case 401:
        //验证失败的情况
        console.log(msg);
        break;  
    }
}
// ---------------------------------------------------------------------
// 检查验证码是否正确
// ---------------------------------------------------------------------
function changeCode(){
    // 修改验证码
    $("#captcha_img").attr('src','/captcha?id='+uuid());

    //验证码设定为 false
    $("#codeValid").val("false");
    //清空以前的验证码
    $("#code").val("");
    //清空提示消息
    $("#code_str").val("");
}
// -------------------------------------------------------------------------------------------
// 生成UUID
// -------------------------------------------------------------------------------------------
function uuid(){
    // 获取系统当前的时间
    var d = new Date().getTime();
    // 替换uuid里面的x和y
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
      // 取余 16进制
      var r = (d + Math.random()*16)%16 | 0;
      // 向下去整
      d = Math.floor(d/16);
      // toString 表示编程16进制的数据
      return (c=='x' ? r : (r&0x3|0x8)).toString(16);
    });
    return uuid;
};
// ---------------------------------------------------------------------
// 检查验证码是否正确
// ---------------------------------------------------------------------
function codeIsError(){
    var error = true;
    var codeStr = $("#code").val();
    if(codeStr == ""){
        setCodeInfo("code_str",error,"验证码不能为空");
        return error;
    }
    // 请求地址,你们最好注意一下,这个地方可能报错需要修改,
    $.ajax({  
        type : "post",  // 使用提交的方法 post、get
        url : contextPath()+"/chkCode",   // 提交的地址
        data : { code:$("#code").val() },  // 数据
        async : false,   // 配置是否
        dataType:"json",// 返回数据类型的格式
        success : function(data){  // 回调操作
          console.log(data);
          error = data.error;

          setCodeInfo("code_str",error,data.msg);
        }  
    });
    return error;
}
// 设定验证码的错误提示消息
function setCodeInfo(elementId,error,msg){
    if(error){
        $("#"+elementId).html("<font color='red'>"+msg+"</font>");
    }else{
        $("#"+elementId).html("<font color='blue'>"+msg+"</font>");
    }
}
// 获取到当前项目的名称
var contextPath = function() { 
    var path = "/" + location.pathname.split("/")[1]; 
    // 当项目的目录是根目录的情况
    if(path == "/login"){
        return "";
    }else{
        return path;
    }
}

登录测试

测试,我直接通过ajax方式提交代码,然后获取到页面中返回的状态吗,根据状态吗来返回请求消息。
这里写图片描述

原理

1、登录分析

根据登录抓包,来获取传递到服务器上的信息
这里写图片描述

2、返回值分析

根据返回值,还有返回的类容来判断是否登录成功
这里写图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狂飙的yellowcong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值