大家都知道,通過抓包軟件(如Charles),可以在App運行時,很輕易的獲取網絡請求的API.如果有人惡意的不斷向這個API發送請求,就有可能造成API的崩潰.為了防止這種攻擊,可以在服務器進行處理.
服務端首先判斷網絡請求是否帶有事先約定的唯一參數.符合情況的才會返回數據.這個參數也就是通常所謂的token,像Weibo接口的設計就采用這種方式.那么在自己的App中該如何實現呢?下面是我在項目實際開發中設計的方式.
網絡請求防攻擊的設計.png
發送請求時,先判斷是否已經請求到token.如果沒有token,轉向請求token的接口請求token.這樣設計,能能將惡意攻擊集中到生成token的接口.然后在生成token的接口,與后臺協調防止攻擊的方式,如要求請求頭需要添加特別的關鍵字.
PS:在swift3.0實現上述邏輯的過程中,有一些需要注意的坑:
1 URLSession的使用
func registerDevice() -> Void {
let device = UIDevice.current
let baseUrl = URL(string: "https://www.baidu.com" )!
let postRequest = NSMutableURLRequest(url: baseUrl)
postRequest.httpMethod = "POST"
let httpBody = "httpBody "
postRequest.httpBody = httpBody.data(using: String.Encoding.utf8)
//session實現同步請求
let semaphore = DispatchSemaphore(value: 0)
let session = URLSession.shared
//respose: 響應頭 try的使用方法
let dataTask = session.dataTask(with: postRequest as URLRequest) { (data, respose, error) in
semaphore.signal()
if error != nil {
gxPrint(item: "設備注冊請求錯誤:\nrespose:\(respose)\nerror:\(error)")
return
}
if data == nil {return}
do {
let dict = try JSONSerialization.jsonObject(with: data!, options: []) as! NSDictionary
if (dict["success"] as! Int) == 1 {
let token = dict["value"] as! String
// debugPrint("\(token)")
UserDefaults.standard.set(token, forKey: UserKeys.GXAppDevice_token)
UserDefaults.standard.synchronize()
}else {
//處理錯誤
} catch {}
}
dataTask.resume()
semaphore.wait()
}
swift3.0中session的dataTask方法需要將NSMutableURLRequest轉化成URLRequest!
其中semaphore可以在URLSession中實現同步請求,參考:
http://blog.csdn.net/chwow/article/details/51537685
2 swift3.0中方法的名字和參數類型有很多變化.如果遇到很奇怪的問題,可以將正確的語法拷貝到工程項目中,點擊XCode的自動修改.(我不會告訴你session的問題,讓我糾結了一晚上).
由于工作的原因,對部分代碼進行了刪改.如果有什么異常,歡迎留言~