网易的图片校验功能流程

许多网站为了防止注册或者登入界面被人盗刷,会有很多校验,一般很多人会用到验证码,种类很多

1:数字验证码

2:图片验证码

3:短信验证码

4:邮件验证 等等

 

 

其实目的都是一样,防止接口被人攻击,这里我用图片验证码做一下实例说明。接口用的是网易的,需要收费

 

效果都清楚了,现在关键是如何实现功能:

第一,需要引用网易的js

    <script src="https://cstaticdun.126.net/load.min.js"></script>@*网易云盾*@

第二:添加 Html按钮

        @*start20191015 新增手机验证码*@
                        <div class="reg_item">
                            <span class="reg_item_span fl" style="width: 18%;">
                                <i class="reg_xh">*</i>@Html.Lang("UserCenter_dxyzm")
                            </span>

                            <div class="reg_input fl" style="width: 50%;">
                                @Html.TextBoxFor(Model => Model.authCode, new { @class = "lg_input", autocomplete = "off", placeholder = @Html.Lang("Account_0021"), maxlength = "6" })
                                @*<input type="text" id="authCode" maxlength="6" class="lg_input" autocomplete="off" placeholder="@Html.Lang("Account_0021")" />*@
                            </div>
                            <div id="captcha"></div> <!-- 验证码容器元素定义 -->
                            <input type="button" width="120" style="height: 39px; position: absolute; right: 22%;" id="btnAuthCodeL" title="@Html.Lang("Account_fcode")" value="@Html.Lang("Account_fcode")" />

                        </div>

                        <input type="hidden" value="123456" id="ValidateCode" name="ValidateCode" /><!-- 固定值 -->
                        @*end*@

第三:添加关联js:

    // 网易云盾  初始化方法
    var captchaIns;
    initNECaptcha({
    element: '#captcha',
    captchaId: '663464f032c94867677fb676b49bd66',  // 这个是假的,这个是需要付费的
    mode: 'popup',
    width: '320px',
    onVerify: function (err, data) {
         if (err != undefined ||data == undefined ||data.validate == undefined) {
             $.fn.showAlert("@Html.Lang("Account_0101")");
             return;
        }
        if (!err) {
            SendSMSLoginCode();
            captchaIns.refresh();
        }
    }
}, function (instance) {
    captchaIns = instance
        }, function (err) { });

 

 

 

$("#btnAuthCodeL").click(function () {
    var phoneNo = $.trim($("#Contact").val());
    if (!phoneNo.isMobile()) {
        $.fn.showAlert("@Html.Lang("UserCenter_0014")");
        $("#Contact").focus();
        return;
    }
    var _code = $("input[name='NECaptchaValidate']").val();
    if (_code == "" || _code.length == 0) {
        captchaIns && captchaIns.popUp()
        return;
    }
});

    //发送验证码
function SendSMSLoginCode() {
    var phoneNo = $.trim($("#Contact").val());
    var _code = $("input[name='NECaptchaValidate']").val();
    $.ajax({
        url: '@Url.Action("YdSMSLoginCode", "Account")',
        data: {
            mobile: phoneNo,
            NECaptchaValidate: _code
        },
        dataType: 'Json',
        type: 'Post',
        success: function (data) {
            if (data.result) {
                $("#btnAuthCodeL").attr("disabled", "disabled");
                $.fn.showAlert(AnyOneQueryOrder_VerificationCodeSended + phoneNo + AnyOneQueryOrder_NoteToReceive);
                // 进行修改 按钮文字
                setCodeButtonText();
                $("#qyzm").attr("readonly", "readonly"); //禁用验证码框
            } else {
                $.fn.showAlert(data.message);
                captchaIns && captchaIns.refresh();
            }
        },
        error: function () {
            $.fn.showAlert(ServerExceptional_Const);
            captchaIns && captchaIns.refresh();
        }
    });
 }
    var flagTime = 180;

    function setCodeButtonText() {
        if (flagTime > 0) {
            flagTime--;
            $("#btnAuthCodeL").val(AnyOneQueryOrder_Remainder + flagTime + AnyOneQueryOrder_Second);
            id_of_setinterval = setTimeout(setCodeButtonText, 1000);
            $("#btnAuthCodeL").attr("title", AnyOneQueryOrder_Remainder + flagTime + AnyOneQueryOrder_Second);
        } else {
            flagTime = 180;
            clearTimeout(id_of_setinterval);
            $("#btnAuthCodeL").removeAttr("disabled");
            $("#btnAuthCodeL").val(AnyOneQueryOrder_GetVerificationCode);
            $("#btnAuthCodeL").attr("title", '@Html.Lang("Account_fcode")');
            $("#qyzm").removeAttr("readonly");//取消验证码的只读
            $("#imgCode1").removeAttr("disabled");//取消验证码图片点击
            $("#imgCode1").bind("click", function () { flush('imgCode1'); });
            flush('imgCode1');//刷新验证码
        }
    }
 

第四:控制器后台代码逻辑实现

 /// <summary>
        /// 快捷登录时获取短信验证码 易盾验证码获取
        /// Create by suhua
        /// </summary>
        /// <returns></returns>
        public ActionResult YdSMSLoginCode(string mobile, string NECaptchaValidate)
        {

           if (String.IsNullOrEmpty(mobile) || String.IsNullOrEmpty(NECaptchaValidate))
            {
                return Json(new { Result = false, Message = "请求参数错误" });
            }

        #region 网易云盾验证 update by suhua 20180516
            string apiUrl = ConfigCenterValue.Instance.NetEaseDunApiUrl; //易盾url
            string captchaId = ConfigCenterValue.Instance.NetEaseDunCaptchaId; //易盾captchaId
            string secretId = ConfigCenterValue.Instance.NetEaseDunSecretId; //易盾secretId
            string secretKey = ConfigCenterValue.Instance.NetEaseDunSecretKey; //易盾secretKey

            NECaptchaVerifier verifier = new NECaptchaVerifier(apiUrl, captchaId, new NESecretPair(secretId, secretKey));
            bool verifyResult = verifier.verify(NECaptchaValidate, null);
            if (!verifyResult)
            {
                return Json(new { Result = false, Message = LocalizationConfig.langInner(this.HttpContext, "Account_0083") });
            }
            #endregion

 

 }

 

第五:后台校验网易云的验证是否正确:

   

// <summary>
    /// 易盾验证码二次校验接口简单封装demo
    /// </summary>
    public class NECaptchaVerifier
    {
        public static string REQ_VALIDATE = "NECaptchaValidate"; // 二次验证带过来的validate

        private string apiUrl = string.Empty;//接口地址
        private string captchaId; // 验证码id
        private NESecretPair secretPair; // 密钥对
        private readonly string VERSION = "v2";
        private readonly HttpClient client = Utils.makeHttpClient();

        public NECaptchaVerifier(string apiUrl, string captchaId, NESecretPair secretPair)
        {
            this.captchaId = captchaId;
            this.secretPair = secretPair;
            this.apiUrl = apiUrl;
        }

        /// <summary>
        /// 向易盾验证码后台发起二次校验请求
        /// </summary>
        /// <param name="validate">二次校验请求字符串</param>
        /// <param name="user">当前用户信息,可以为空字符串</param>
        /// <returns></returns>
        public bool verify(string validate, string user)
        {
            if (String.IsNullOrEmpty(validate))
            {
                return false;
            }
            user = (user == null) ? "" : user;
            Dictionary<String, String> parameters = new Dictionary<String, String>();
            long curr = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
            String time = curr.ToString();

            parameters.Add("captchaId", captchaId);
            parameters.Add("validate", validate);
            parameters.Add("user", user);

            // 1.设置公共参数
            parameters.Add("secretId", secretPair.secretId);
            parameters.Add("version", VERSION);
            parameters.Add("timestamp", time);
            parameters.Add("nonce", new Random().Next().ToString());

            // 2.生成签名信息
            String signature = Utils.genSignature(secretPair.secretKey, parameters);
            parameters.Add("signature", signature);

            // 3.发送HTTP请求
            String response = Utils.doPost(client, apiUrl, parameters, 5000);
            return verifyRet(response);
        }

        /// <summary>
        /// 解析二次校验接口返回的结果
        /// </summary>
        /// <param name="response"></param>
        /// <returns></returns>
        private bool verifyRet(string response)
        {
            if (String.IsNullOrEmpty(response))
            {
                AppLog.Write("网易云盾验证失败:无返回值", LogMessageType.Warn);
                return false;
            }
            try
            {
                JObject j = JObject.Parse(response);
                JToken jToken;
                j.TryGetValue("result", out jToken);
                bool isOk = jToken.ToObject<Boolean>();
                if (!isOk)
                    AppLog.Write(string.Format("网易云盾验证失败:{0}", response), LogMessageType.Warn);
                return isOk;
            }
            catch (Exception e)
            {
                AppLog.Write(string.Format("网易云盾验证失败:{0}/{1}", response, e.ToString()), LogMessageType.Error);
            }
            return false;
        }
    }

    /// <summary>
    /// 易盾验证码密钥对
    /// </summary>
    public class NESecretPair
    {
        public string secretId; // 密钥对id
        public string secretKey; // 密钥对key

        public NESecretPair(string secretId, string secretKey)
        {
            this.secretId = secretId;
            this.secretKey = secretKey;
        }
    }

第六: Utils类的方法

public class Utils
    {
        /// <summary>
        /// 根据请求参数生成对应的签名信息
        /// </summary>
        /// <param name="secretKey"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public static String genSignature(String secretKey, Dictionary<String, String> parameters)
        {
            parameters = parameters.OrderBy(o => o.Key).ToDictionary(o => o.Key, p => p.Value);

            StringBuilder builder = new StringBuilder();
            foreach (KeyValuePair<String, String> kv in parameters)
            {
                builder.Append(kv.Key).Append(kv.Value);
            }
            builder.Append(secretKey);
            String tmp = builder.ToString();
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] result = md5.ComputeHash(Encoding.UTF8.GetBytes(tmp));
            builder.Clear();
            foreach (byte b in result)
            {
                builder.Append(b.ToString("x2").ToLower());
            }
            return builder.ToString();
        }

        public static HttpClient makeHttpClient()
        {
            HttpClient client = new HttpClient() { };
            client.DefaultRequestHeaders.Connection.Add("keep-alive");
            return client;
        }

        /// <summary>
        /// 发起HTTP-Post请求
        /// </summary>
        /// <param name="client">httpClient对象</param>
        /// <param name="url">请求接口url</param>
        /// <param name="parameters">请求参数</param>
        /// <param name="timeOutInMillisecond">超时时间</param>
        /// <returns></returns>
        public static String doPost(HttpClient client, String url, Dictionary<String, String> parameters, int timeOutInMillisecond)
        {
            try
            {
                HttpContent content = new FormUrlEncodedContent(parameters);
                Task<HttpResponseMessage> task = client.PostAsync(url, content);
                if (task.Wait(timeOutInMillisecond))
                {
                    HttpResponseMessage response = task.Result;
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        Task<string> result = response.Content.ReadAsStringAsync();
                        result.Wait();
                        return result.Result;
                    }
                }
            }
            catch (Exception ex)
            {
                AppLog.Write(string.Format("网易云盾验证码异常:{0}", ex.ToString()), LogMessageType.Error);
            }
            return null;
        }
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值