c#实现简单Token口令验证-阿里云开发者社区

开发者社区> dasein58> 正文

c#实现简单Token口令验证

简介:   最近一个项目发现手机验证码总是被人盗刷,一秒钟刷了1百多个,很明显这种行为是通过软件自动提交的,自动发帖机原理类似,解决这个问题目前有两个方案。   出现这个问题原因:请求手机验证码Api时没有任何带任何验证,只要请求了手机号正确就执行发送操作,软件或代码很容易伪造请求过程。   解决方案有很多种,可以选择下面一种或几种组合起来使用。   方案1:用户获取手机验证码时候弹出图片验证码,输入后再发送。
+关注继续查看

  最近一个项目发现手机验证码总是被人盗刷,一秒钟刷了1百多个,很明显这种行为是通过软件自动提交的,自动发帖机原理类似,解决这个问题目前有两个方案。

  出现这个问题原因:请求手机验证码Api时没有任何带任何验证,只要请求了手机号正确就执行发送操作,软件或代码很容易伪造请求过程。

  解决方案有很多种,可以选择下面一种或几种组合起来使用。

  方案1:用户获取手机验证码时候弹出图片验证码,输入后再发送。

  优点:增加伪造请求成功的难度,必须输入验证码才可以发送,如果是软件,软件需要有图片验证码识别功能。

  缺点:用户体验不好,增加了普通用户的操作步骤。

  方案2:增加ip黑名单,即检测请求ip的发送频率,如同一个ip一分钟内请求多少次后屏蔽ip。

  缺点:一些软件有主动更换ip的功能,这种方式效果不是很好。

  方案3:加上token口令验证

  在Api中增加口令验证,即每次请求必须带上token,token验证正确了才执行发送操作。

  这个方案为了替代方案1,因为有的公司对前端体验要求极高,增加用户操作步骤后用户体验不好。

  这里token可以放在数据库中,也可以放在内存中,个人建议放在内存中,速度快,查询快,至于冗余的问题,可以增加一个BuildDate来保存生成时间。

  Token描述类

  public class TokenDescriptor

  {

  ///

  /// 客户端唯一Id,必须保证唯一性

  ///

  public string ClientId { get; set; }

  ///

  /// token

  ///

  public string Token { get; set; }

  ///

  /// token生成日期

  ///

  public DateTime BuildDate { get; set; }

  }

  token处理类

  public class TokenFactoryBLL

  {

  private string _ClientId;

  private static List _TokenList;

  static TokenFactoryBLL()

  {

  _TokenList=new List();

  }

  ///

  ///

  ///

  ///
  public TokenFactoryBLL(HttpRequestBase httpRequestBase)

  {

  _ClientId=StringHelper.ClientId(httpRequestBase);

  ClearExpired();

  }

  ///

  /// 可用于远程api

  ///

  ///
  public TokenFactoryBLL(string clientId)

  {

  _ClientId=clientId;

  ClearExpired();

  }

  ///

  /// 生成口令

  ///

  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;

  }

  ///

  /// 验证token

  ///

  ///
  ///

  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;

  }

  ///

  /// 移除对应客户端的所有token

  ///

  ///
  public void Remove()

  {

  _TokenList.RemoveAll(c=> c.ClientId.Equals(_ClientId, StringComparison.OrdinalIgnoreCase));

  }

  ///

  /// 清理过期的token,过期时间10分钟

  ///

  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的方法:

  ///

  /// 获取并生成客户端唯一Id,保存在cookie中;

  ///

  ///

  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;

  }

  ///

  /// 获取客户端ip

  ///

  ///

  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之前,先第一次请求二手QQ卖号平台获取token,然后带上token验证通过后后再请求api。

  这个方案肯定没有验证码的防护效果好,只是增加了伪造请求的步骤,因为现在很多模拟请求的软件都是一次性请求,所以还是能防护大部分的软件。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
9497 0
阿里云服务器ECS远程登录用户名密码查询方法
阿里云服务器ECS远程连接登录输入用户名和密码,阿里云没有默认密码,如果购买时没设置需要先重置实例密码,Windows用户名是administrator,Linux账号是root,阿小云来详细说下阿里云服务器远程登录连接用户名和密码查询方法
11214 0
windows server 2008阿里云ECS服务器安全设置
最近我们Sinesafe安全公司在为客户使用阿里云ecs服务器做安全的过程中,发现服务器基础安全性都没有做。为了为站长们提供更加有效的安全基础解决方案,我们Sinesafe将对阿里云服务器win2008 系统进行基础安全部署实战过程! 比较重要的几部分 1.
9055 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13186 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
4012 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
6895 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,云吞铺子总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系统盘、创建快照、配置安全组等操作如何登录ECS云服务器控制台? 1、先登录到阿里云ECS服务器控制台 2、点击顶部的“控制台” 3、通过左侧栏,切换到“云服务器ECS”即可,如下图所示 通过ECS控制台的远程连接来登录到云服务器 阿里云ECS云服务器自带远程连接功能,使用该功能可以登录到云服务器,简单且方便,如下图:点击“远程连接”,第一次连接会自动生成6位数字密码,输入密码即可登录到云服务器上。
21912 0
+关注
765
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载