|

关于阿里云滑块验证的介绍:
滑动验证是服役于阿里巴巴人机识别第一线的验证码产品。用户通过简单的右滑交互,无需思考即可通过验证。
文档链接:https://help.aliyun.com/document_detail/66317.html
产品购买链接:https://yundun.console.aliyun.com/?p=afs#/person-machine
阿里云滑块验证码大体流程如下:
网页加载完->获取到验证码->用户滑动滑块验证码->向阿里云接口获取csessionid、sig参数->带着csessionid、sig、nc_token、nc_login参数向我们后台接口请求->后台拿到参数去阿里云接口验证->返回给前端验证结果
效果图:
html代码如下:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <!-- 国内使用 -->
- <script type="text/javascript" charset="utf-8" src="//g.alicdn.com/sd/ncpc/nc.js?t=2015052012"></script>
- <!-- 若您的主要用户来源于海外,请替换使用下面的js资源 -->
- <!-- <script type="text/javascript" charset="utf-8" src="//aeis.alicdn.com/sd/ncpc/nc.js?t=2015052012"></script> -->
- <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
- </head>
- <body>
- <div><h1>阿里云滑动验证码测试</h1><p>by:http://www.itsvse.com</p></div>
- <div><label>ip:</label><span id="ip"></span></div>
- <br />
- <div id="your-dom-id" class="nc-container"></div> <!--No-Captcha渲染的位置,其中 class 中必须包含 nc-container-->
- <br />
- <div><label>伪造csessionid:</label><input type="checkbox" id="weizao"/></div>
- <br />
- <div><label>测试结果:</label><span id="res"></span></div>
- <script type="text/javascript">
- var nc_token = ["FFFF0N00000000005A40", (new Date()).getTime(), Math.random()].join(':');
- var NC_Opt =
- {
- renderTo: "#your-dom-id",
- appkey: "xxxxxxx",
- scene: "nc_login",
- token: nc_token,
- customWidth: 300,
- trans:{"key1":"code0"},
- elementID: ["usernameID"],
- is_Opt: 0,
- language: "cn",
- isEnabled: true,
- timeout: 3000,
- times:5,
- apimap: {
- // 'analyze': '//a.com/nocaptcha/analyze.jsonp',
- // 'get_captcha': '//b.com/get_captcha/ver3',
- // 'get_captcha': '//pin3.aliyun.com/get_captcha/ver3'
- // 'get_img': '//c.com/get_img',
- // 'checkcode': '//d.com/captcha/checkcode.jsonp',
- // 'umid_Url': '//e.com/security/umscript/3.2.1/um.js',
- // 'uab_Url': '//aeu.alicdn.com/js/uac/909.js',
- // 'umid_serUrl': 'https://g.com/service/um.json'
- },
- callback: function (data) {
- window.console && console.log(nc_token)
- window.console && console.log(data.csessionid)
- window.console && console.log(data.sig)
- var csessionid = data.csessionid;
- if ($("#weizao").prop("checked"))
- {
- csessionid = "xxxxxxxxxxxxx";
- }
- var par = "SessionId=" + csessionid + "&Sig=" + data.sig + "&Token=" + nc_token + "&Scene=nc_login";
- $.get("/test.ashx?" + par, function (res) {
- //alert(res.msg);
- $("#res").html(res.msg);
- });
- }
- }
- var nc = new noCaptcha(NC_Opt)
- nc.upLang('cn', {
- _startTEXT: "请按住滑块,拖动到最右边",
- _yesTEXT: "验证通过",
- _error300: "哎呀,出错了,点击<a href="javascript:__nc.reset()">刷新</a>再来一次",
- _errorNetwork: "网络不给力,请<a href="javascript:__nc.reset()">点击刷新</a>",
- });
- $(function () {
- $.get("/ip.ashx", function (data) {
- $("#ip").html(data.msg);
- });
- });
- </script>
- </body>
- </html>
复制代码 test.ashx接口代码如下:
- using Aliyun.Acs.afs.Model.V20180112;
- using Aliyun.Acs.Core;
- using Aliyun.Acs.Core.Profile;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Routing;
- namespace ali_captcha
- {
- /// <summary>
- /// test 的摘要说明
- /// </summary>
- public class test : IHttpHandler
- {
- private static readonly string accessKeyId = System.Configuration.ConfigurationManager.AppSettings["accessKeyId"];
- private static readonly string secret = System.Configuration.ConfigurationManager.AppSettings["secret"];
- private static readonly string AppKey = System.Configuration.ConfigurationManager.AppSettings["AppKey"];
- private static IAcsClient client = null;
- static test()
- {
- IClientProfile profile = DefaultProfile.GetProfile("cn-hangzhou", accessKeyId, secret);
- client = new DefaultAcsClient(profile);
- DefaultProfile.AddEndpoint("cn-hangzhou", "cn-hangzhou", "afs", "afs.aliyuncs.com");
- }
- public bool IsReusable => false;
- public void ProcessRequest(HttpContext context)
- {
- context.Response.ContentType = "application/json;charset=utf-8";
-
- AuthenticateSigRequest request = new AuthenticateSigRequest();
- request.SessionId = context.Request.QueryString["SessionId"];// 必填参数,从前端获取,不可更改,android和ios只变更这个参数即可,下面参数不变保留xxx
- request.Sig = context.Request.QueryString["Sig"];// 必填参数,从前端获取,不可更改
- request.Token = context.Request.QueryString["Token"];// 必填参数,从前端获取,不可更改
- request.Scene = context.Request.QueryString["Scene"];// 必填参数,从前端获取,不可更改
- request.AppKey = AppKey;// 必填参数,后端填写
- request.RemoteIp = IPHelper.GetRemoteIp(context.Request.RequestContext);// 必填参数,后端填写
- try
- {
- AuthenticateSigResponse response = client.GetAcsResponse(request);// 返回code 100表示验签通过,900表示验签失败
- if (response.Code == 100)
- {
- context.Response.Write("{"ret":true,"msg":"ok"}");
- }
- else {
- //{"ret":true,"msg":"ok"}
- context.Response.Write("{"ret":false,"msg":"no"}");
- }
-
- // TODO
- }
- catch (Exception e)
- {
- Console.WriteLine(e.ToString());
- }
- }
- }
-
- }
复制代码 ip.ashx接口代码:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Routing;
- namespace ali_captcha
- {
- /// <summary>
- /// ip 的摘要说明
- /// </summary>
- public class ip : IHttpHandler
- {
- public void ProcessRequest(HttpContext context)
- {
- context.Response.ContentType = "application/json;charset=utf-8";
- string ip = IPHelper.GetRemoteIp(context.Request.RequestContext);
- context.Response.Write("{"ret":true,"msg":"" + ip + ""}");
- }
- public bool IsReusable => true;
- }
-
- public class IPHelper
- {
- /// <summary>
- /// 是否获取真实ip
- /// </summary>
- private static readonly bool IsRemoteIp = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["IsRemoteIp"]);
- /// <summary>
- /// 获取客户端IP
- /// </summary>
- /// <param name="req"></param>
- /// <returns></returns>
- public static string GetRemoteIp(RequestContext req)
- {
- if (!IsRemoteIp) return "8.8.8.8";//返回一个假的ip
- string result = req.HttpContext.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
- if (string.IsNullOrEmpty(result))
- {
- result = req.HttpContext.Request.ServerVariables["REMOTE_ADDR"];
- }
- if (string.IsNullOrEmpty(result))
- {
- result = req.HttpContext.Request.UserHostAddress;
- }
- if (string.IsNullOrEmpty(result))
- {
- result = "0.0.0.0";
- }
- return result;
- }
- }
- }
复制代码
在后台验证的时候,有6个参数,其中4个参数是前台获取的,2个参数是后台填写,如下:
- request.SessionId = context.Request.QueryString["SessionId"];// 必填参数,从前端获取,不可更改,android和ios只变更这个参数即可,下面参数不变保留xxx
- request.Sig = context.Request.QueryString["Sig"];// 必填参数,从前端获取,不可更改
- request.Token = context.Request.QueryString["Token"];// 必填参数,从前端获取,不可更改
- request.Scene = context.Request.QueryString["Scene"];// 必填参数,从前端获取,不可更改
- request.AppKey = AppKey;// 必填参数,后端填写
- request.RemoteIp = IPHelper.GetRemoteIp(context.Request.RequestContext);// 必填参数,后端填写
复制代码
RemoteIp参数,我从阿里云官方文档,一直没有找到该参数的解释。。。。。从字面意思,我们可以看出该参数是请求者的ip地址。。。
web.config有一项配置:
- <add key="IsRemoteIp" value="false"/>
复制代码
IsRemoteIp为true时,我就返回伪造的ip,也就是8.8.8.8,如果为false的时候,我们就返回用户的真实ip,如下图:
测试结果,无论是伪造的请求ip,还是真实的请求者ip,都不影响验证结果,由此表明,RemoteIp对验证结果几乎应该没有任何影响。。。。
如果伪造csessionid的话,验证是失败的,如果伪造Token的话,验证也是失败的!
下图是伪造token的值:
(完)
源码下载:
|
上一篇:[Windows API]供C#查询API的使用代码助手[附源码]下一篇:挥别Windows时代!微软解散工程师团队,主攻云服务
|