iOS防止用户恶意点击场景分析、防止用户恶意点击方法之本地动态验证码生成

场景分析:

1. app中使用手机号码获取验证码作为登录条件。(与各种电话平台合作,一般价格为 几分 - 1毛不等)

   2. 电商app ,实名认证接口。 输入用户姓名与身份证号码进行实名认证 (一般公司都是与其他平台进行合作,基本上价格为 1次验证为1元左右)。

        3. 电商app, 实时获取订单的物流信息, 输入物流号与物流公司,就可以获取到物流信息 (我们公司现在用的是快递100平台,分为了海外物流与国内物流 ,成本也是根据物流查询次数来计算价格。每天不超过2000次是免费的,但是超出的话,费用就相当贵了,不过对大公司来说,这个不算什么,也就包年20 - 30W,具体费用,可以与他们客服人员联系。)

4. 在线投票系统。 通过手机号码来进行投票。 

解决办法:

针对以上问题。 以下是应对办法。 

   1. 手机号码登录 - 注册, 加上获取验证码间隔时间, 每一分钟只能获取一次。

  2. 实名认证接口 - 需要由服务器端进行配合, 通过手机UUID - 或者是ip地址 - 用户id - 来进行每日次数限定

3.  手机号码投票系统  -  可以通过限定号码每日的最大发送数量

  4. 还有一种,是比较常见的,就是通过输入验证码,进行防止机器人通过恶意操作进行频繁点击,也可以防止人为的故意点击。  这样就可以防止用户在查询订单的时候,循环点击查询订单物流信息,最大程度上的减少运营的成本。替公司减少开支。 


下面是编码过程; 

    生成验证码的具体代码: swift版本验证码生成项目demo地址: https://github.com/zhonggaorong/GenerateCodeDemo

项目效果:


 GenerateCodeView.swift

//
//  GenerateCodeView.swift
//  GenerateCodeDemo
//
//  Created by 张国荣 on 16/8/12.
//  Copyright © 2016年 BateOrganization. All rights reserved.
//

import UIKit


//extension String {
//    subscript (r: Range<Int>) -> String {
//        get {
//            let subStart = advence(self.startIndex, r.startIndex, self.endIndex)
//            let subEnd = advance(subStart, r.endIndex - r.startIndex, self.endIndex)
//            return self.substringWithRange(Range(start: subStart, end: subEnd))
//        }
//    }
//    func substring(from: Int) -> String {
//        let end = countElements(self)
//        return self[from..<end]
//    }
//    func substring(from: Int, length: Int) -> String {
//        let end = from + length
//        return self[from..<end]
//    }
//}


class GenerateCodeView: UIView {
    //随机产生颜色
    var randomColor = (Float)(arc4random()%255)/100.0
    // 验证码位数
    var codeNumber:Int = 4
    var codeString:String = ""
    //随机验证码数据源
    var dataArray:[String] = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.layer.cornerRadius = 5.0
        self.layer.masksToBounds = true
        self.changeBgColor()
        self.CreateGenerateCodeAction()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    //改变背景颜色
    func changeBgColor() -> Void {
        self.backgroundColor = self.generateColor()
    }
    
    // 随机验证码的view实现
    func CreateGenerateCodeAction() -> Void {
        codeString = ""
        for _ in 0...codeNumber-1 {
            var d = random()%dataArray.count-1
            if (d <= 0) {
                d = 0
            }else if (d >= dataArray.count) {
                d = dataArray.count - 1
            }
            print("---totalcount %d currentCount %d",dataArray.count, d)
            codeString = codeString.stringByAppendingString(dataArray[d])
        }
        self.setNeedsDisplay()
    }
    
    // 随机颜色
    func generateColor() -> UIColor {
        return UIColor.init(colorLiteralRed: (Float)(arc4random()%256)/256.0, green: (Float)(arc4random()%256)/256.0, blue: (Float)(arc4random()%256)/256.0, alpha: 1.0)
    }
    
    
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        
        self.changeBgColor()
        self.CreateGenerateCodeAction()
    }
    
    // 把随机码画上去
    override func drawRect(rect: CGRect) {
        
        if codeString.isEmpty {
            return;
        }
        
        self.backgroundColor = self.generateColor()
        
        let textString:String = codeString
        let charSize = textString.substringToIndex(textString.startIndex).sizeWithAttributes([NSFontAttributeName : UIFont.systemFontOfSize(16)])
        
        let width = rect.size.width/CGFloat(codeNumber) - charSize.width - 5;
        let hight = rect.size.height - charSize.height;
        
        var mypoint:CGPoint
        // 计算每个字符
        
        var point_x:CGFloat
        var point_y:CGFloat
        
        let intWidth = UInt32(Float(width))
        let intHight = UInt32(Float(hight))
        
        for i in 0...textString.characters.count-1 {
            let c:CGFloat = CGFloat(i)
            let myIn:Int = Int(i)
            point_x = (CGFloat)(arc4random()%intWidth) + rect.size.width/(CGFloat)(textString.characters.count) * c
            point_y = (CGFloat)(arc4random()%intHight)
            mypoint = CGPointMake(point_x, point_y)
            
            let charStr = textString[textString.startIndex.advancedBy(myIn)]

            let bb:String = ""
             let t = bb.stringByAppendingString(String(charStr))
            t.drawAtPoint(mypoint,withAttributes:([NSFontAttributeName : UIFont.systemFontOfSize(16)]))
        }
        
        
        let context = UIGraphicsGetCurrentContext()
        CGContextSetLineWidth(context, 1)
        var px:CGFloat = 0.0
        var py:CGFloat = 0.0
        for _ in 0...5 {
            CGContextSetStrokeColorWithColor(context, self.generateColor().CGColor)
            px = CGFloat(arc4random()%UInt32(Float(rect.size.width)))
            py = CGFloat(arc4random()%UInt32(Float(rect.size.height)))
            CGContextMoveToPoint(context, px, py)
            px = CGFloat(arc4random()%UInt32(Float(rect.size.width)))
            py = CGFloat(arc4random()%UInt32(Float(rect.size.height)))
            CGContextAddLineToPoint(context, px, py)
            CGContextStrokePath(context)
        }
    }
    
    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
   
    */

}

//
//  ViewController.swift
//  GenerateCodeDemo
//
//  Created by 张国荣 on 16/8/12.
//  Copyright © 2016年 BateOrganization. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var myCodeTextField: UITextField!
    @IBOutlet weak var generateCodeView: GenerateCodeView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        generateCodeView.CreateGenerateCodeAction()
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func testingAction(sender: AnyObject) {
        if generateCodeView.codeString == myCodeTextField.text {
            var alert = UIAlertView.init(title:"恭喜", message: "验证通过", delegate: nil, cancelButtonTitle: "确 认")
            alert.show()
        }else {
            var alert = UIAlertView.init(title:"失望", message: "验证失败", delegate: nil, cancelButtonTitle: "确 认")
            alert.show()
        }
        
        myCodeTextField.resignFirstResponder()
    }
    

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.view.endEditing(true)
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值