亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.430618.com 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

最近一個項目發現手機驗證碼總是被人盜刷,一秒鐘刷了1百多個,很明顯這種行為是通過軟件自動提交的,自動發帖機原理類似,解決這個問題目前有兩個方案。

出現這個問題原因:請求手機驗證碼Api時沒有任何帶任何驗證,只要請求了手機號正確就執行發送操作,軟件或代碼很容易偽造請求過程。

解決方案有很多種,可以選擇下面一種或幾種組合起來使用。

方案1:用戶獲取手機驗證碼時候彈出圖片驗證碼,輸入后再發送。

優點:增加偽造請求成功的難度,必須輸入驗證碼才可以發送,如果是軟件,軟件需要有圖片驗證碼識別功能。

缺點:用戶體驗不好,增加了普通用戶的操作步驟。

方案2:增加ip黑名單,即檢測請求ip的發送頻率,如同一個ip一分鐘內請求多少次后屏蔽ip。

缺點:一些軟件有主動更換ip的功能,這種方式效果不是很好。

方案3:加上token口令驗證

在Api中增加口令驗證,即每次請求必須帶上token,token驗證正確了才執行發送操作。

這個方案為了替代方案1,因為有的公司對前端體驗要求極高,增加用戶操作步驟后用戶體驗不好。

這里token可以放在數據庫中,也可以放在內存中,個人建議放在內存中,速度快,查詢快,至于冗余的問題,可以增加一個BuildDate來保存生成時間。

Token描述類

   public class TokenDescriptor
    {
        /// <summary>
        /// 客戶端唯一Id,必須保證唯一性
        /// </summary>
        public string ClientId { get; set; }
        /// <summary>
        /// token
        /// </summary>

        public string Token { get; set; }

        /// <summary>
        /// token生成日期
        /// </summary>
        public DateTime BuildDate { get; set; }
    }

token處理類

  public class TokenFactoryBLL
    {
        private string _ClientId;
        private static List<TokenDescriptor> _TokenList;

        static TokenFactoryBLL()
        {
            _TokenList = new List<TokenDescriptor>();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="httpRequestBase"></param>
        public TokenFactoryBLL(HttpRequestBase httpRequestBase)
        {
            _ClientId = StringHelper.ClientId(httpRequestBase);
            ClearExpired();
        }

        /// <summary>
        /// 可用于遠程api
        /// </summary>
        /// <param name="clientId"></param>
        public TokenFactoryBLL(string clientId)
        {
            _ClientId = clientId;
            ClearExpired();
        }

        /// <summary>
        /// 生成口令
        /// </summary>
        public string Get()
        {
            if (string.IsNullOrEmpty(_ClientId))
            {
                return null;
            }
            string token = Guid.NewGuid().ToString("N");//guid;
            TokenDescriptor tokenDescriptor = new TokenDescriptor();
            tokenDescriptor.ClientId = _ClientId;
            tokenDescriptor.Token = StringHelper.NewGuid();
            tokenDescriptor.BuildDate = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            _TokenList.Add(tokenDescriptor);
            return token;
        }

        /// <summary>
        /// 驗證token
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public TipsInfo Validate(string token)
        {
            TipsInfo tipsInfo = new TipsInfo();
            if (!_TokenList.Exists(c => c.ClientId.Equals(_ClientId, StringComparison.OrdinalIgnoreCase) && c.Token.Equals(token, StringComparison.OrdinalIgnoreCase)))
            {
                tipsInfo.State = 0;
                tipsInfo.Msg = "token口令驗證失敗";
            }
            return tipsInfo;
        }

        /// <summary>
        /// 移除對應客戶端的所有token
        /// </summary>
        /// <param name="clientId"></param>
        public void Remove()
        {
            _TokenList.RemoveAll(c => c.ClientId.Equals(_ClientId, StringComparison.OrdinalIgnoreCase));
        }


        /// <summary>
        /// 清理過期的token,過期時間10分鐘
        /// </summary>
        private static void ClearExpired()
        {
            for (var i = 0; i < _TokenList.Count; i++)
            {
                TokenDescriptor item = _TokenList[i];
                DateTime startTime = item.BuildDate;
                DateTime endTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                TimeSpan ts = endTime - startTime;
                int minutes = ts.Minutes;
                if (minutes>10)
                {
                    _TokenList.RemoveAt(i);
                }
            }
        }
    }

附上Helper工具類中clientId的方法:

        /// <summary>
        /// 獲取并生成客戶端唯一Id,保存在cookie中;
        /// </summary>
        /// <returns></returns>
        public static string ClientId(HttpRequestBase request) //獲取客戶端唯一Id
        {
            if (request == null)
            {
                return null;
            }
            string clientId = CookieHelper.Get("_clientId_");
            if (string.IsNullOrEmpty(clientId))
            {
                string guid = Guid.NewGuid().ToString("N");//guid
                string ip = StringHelper.GetClientIP().ToString().Replace(".", "").Replace(":", "");
                clientId = guid + ip;
                CookieHelper.Add("_clientId_", clientId);
            }
            return clientId;
        }

        /// <summary>
        /// 獲取客戶端ip
        /// </summary>
        /// <returns></returns>
        public static string GetClientIP()
        {
            if (System.Web.HttpContext.Current == null) return "127.0.0.1";
            string clientIp = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (string.IsNullOrEmpty(clientIp))
            {
                clientIp = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            }
            if (string.IsNullOrEmpty(clientIp))
            {
                clientIp = System.Web.HttpContext.Current.Request.UserHostAddress;
            }
            if (clientIp.IndexOf(",") > 0)
            {
                clientIp = clientIp.Split(',')[0];
            }
            if (!StringHelper.IsIp(clientIp))
            {
                clientIp = "127.0.0.1";
            }
            return clientIp;
        }

前端發送方式需要更改,在請求手機驗證碼的api之前,先第一次請求獲取token,然后帶上token驗證通過后后再請求api。

這個方案肯定沒有驗證碼的防護效果好,只是增加了偽造請求的步驟,因為現在很多模擬請求的軟件都是一次性請求,所以還是能防護大部分的軟件。

分享到:
標簽:Token
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定