Untuk mengonfigurasi kebijakan mitigasi berbasis skenario bagi aplikasi Anda di Konsol Bot Management, Anda harus mengintegrasikan App Protection SDK dari Web Application Firewall (WAF). Topik ini menjelaskan cara mengintegrasikan App Protection SDK ke dalam aplikasi iOS.
Informasi latar belakang
App Protection SDK menandatangani permintaan dari client aplikasi. Server WAF kemudian memverifikasi signature permintaan tersebut untuk mengidentifikasi dan memblokir permintaan serangan, sehingga melindungi aplikasi Anda.
Batasan
SDK iOS tersedia dalam dua versi: versi Identifier for Advertising (IDFA) dan versi non-IDFA. File SDK yang sesuai adalah:
AliTigerTally_IDFA.framework
AliTigerTally_NOIDFA.framework
Jika proyek iOS Anda menggunakan IDFA, kami merekomendasikan agar Anda mengintegrasikan SDK versi AliTigerTally_IDFA. Jika tidak, gunakan versi AliTigerTally_NOIDFA.
Antarmuka
initdapat memakan waktu. Untuk perlindungan optimal, tunggu minimal 2 detik setelah memanggil antarmukainitsebelum memanggil antarmukavmpSign. Meskipun penundaan ini tidak wajib, interval yang lebih pendek dapat mencegah fitur keamanan bekerja secara maksimal. Anda dapat menyesuaikan interval berdasarkan kebutuhan bisnis Anda.App Protection SDK memerlukan iOS versi 9.0 atau yang lebih baru.
Prasyarat
Anda telah memperoleh SDK untuk aplikasi iOS Anda.
Untuk memperoleh SDK, kirimkan ticket untuk menghubungi Ahli teknis produk.
CatatanFile SDK untuk aplikasi iOS diberi nama
tigertally-X.Y.Z-xxxx-ios.zip, dengan X.Y.Z sebagai nomor versi. File tersebut berisi dua file framework dan dua file xcframework.Anda telah memperoleh authentication key SDK (juga dikenal sebagai appkey).
Setelah Anda mengaktifkan Bot Management, Anda dapat Masuk ke Konsol Web Application Firewall 3.0. Dari bilah menu atas, pilih kelompok sumber daya dan wilayah (Chinese Mainland atau Outside Chinese Mainland) untuk instans WAF.. Di panel navigasi sebelah kiri, pilih . Buka tab App Protection dan klik Obtain and Copy AppKey di pojok kanan atas untuk mengambil authentication key SDK. Kunci ini diperlukan untuk inisialisasi SDK dan harus disertakan dalam kode integrasi Anda.
CatatanSetiap Akun Alibaba Cloud memiliki appkey unik untuk semua nama domain yang dilindungi oleh WAF. appkey ini digunakan untuk integrasi SDK di aplikasi Android, iOS, dan HarmonyOS.
Contoh authentication key:
****OpKLvM6zliu6KopyHIhmneb_****u4ekci2W8i6F9vrgpEezqAzEzj2ANrVUhvAXMwYzgY_****vc51aEQlRovkRoUhRlVsf4IzO9dZp6nN_****Wz8pk2TDLuMo4pVIQvGaxH3vrsnSQiK****.
Langkah 1: Buat proyek
Di Xcode, buat proyek iOS menggunakan wizard pengaturan. Contoh berikut menunjukkan struktur direktori proyek.
tigerdemo
tigerdemo
tool
AppDelegate.h
AppDelegate.m
ViewController.h
ViewController.m
main.m
Main.storyboard
LaunchScreen.storyboard
AliTigerTallyApp.entitlements
Info.plistLangkah 2: Integrasikan framework
Tambahkan file SDK, AliTigerTally_IDFA.framework atau AliTigerTally_NOIDFA.framework, ke proyek Anda.
Versi IDFA
Setelah menambahkan file tersebut, atur opsi Embed dari AliTigerTally_IDFA.framework menjadi Do Not Embed.
Versi non-IDFA
Tambahkan AliTigerTally_NOIDFA.framework ke bagian Frameworks, Libraries, and Embedded Content proyek Anda, dan atur Embed menjadi Do Not Embed.
Tambahkan file SDK modul Captcha, AliCaptcha.framework, ke proyek Anda, dan atur opsi Embed-nya menjadi Do Not Embed.
Tambahkan file resource AliCaptcha.bundle ke proyek Anda dengan menambahkannya di Build Phases > Copy Bundle Resources.
Langkah 3: Tambahkan library dependensi
Di bagian Frameworks, Libraries, and Embedded Content proyek Xcode Anda, tambahkan library dependensi berikut.
Library dependensi | Diperlukan untuk IDFA | Diperlukan untuk non-IDFA |
libc++.tbd | Ya | Ya |
libresolv.9.tbd | Ya | Ya |
CoreTelephony.framework | Ya | Ya |
AdSupport.framework | Ya | Tidak |
AppTrackingTransparency.framework | Ya | Tidak |
Langkah 4: Tambahkan flag linker
Di Build Settings, cari Other Linker Flags dan tambahkan flag -ObjC.
Langkah 5: Tambahkan kode integrasi
1. Tambahkan file header
Untuk versi IDFA, tambahkan pernyataan impor berikut:
#import <AliTigerTally_IDFA/AliTigerTally.h>Untuk versi non-IDFA, tambahkan pernyataan impor berikut:
#import <AliTigerTally_NOIDFA/AliTigerTally.h>
2. Konfigurasi penandatanganan data
Tetapkan identifier pengguna akhir kustom untuk bisnis Anda. Hal ini memungkinkan Anda mengonfigurasi kebijakan perlindungan WAF dengan fleksibilitas lebih tinggi.
/** * Menetapkan akun pengguna. * * @param account Informasi akun. */ - (void)setAccount:(NSString *)account;Parameter:
account: Tipe: NSString. String yang mengidentifikasi pengguna. Kami merekomendasikan penggunaan format yang telah didesensitisasi.
Nilai kembalian: Tidak ada.
Contoh:
// Untuk pengguna tamu, Anda dapat melewati setAccount dan langsung melakukan inisialisasi. Setelah pengguna masuk, panggil setAccount dan lakukan inisialisasi ulang. [[AliTigerTally sharedInstance] setAccount:@"testAccount"];
Inisialisasi SDK untuk melakukan pengumpulan data.
Setiap inisialisasi mengumpulkan informasi perangkat satu kali. Anda dapat memanggil fungsi init lagi untuk melakukan inisialisasi ulang pengumpulan data untuk skenario bisnis yang berbeda.
Inisialisasi mendukung tiga mode pengumpulan data: lengkap, privasi kustom, dan non-privasi. Mode non-privasi mengecualikan bidang yang terkait privasi pengguna akhir, seperti IDFA dan IDFV.
CatatanUntuk memenuhi persyaratan internal Anda, pilih mode pengumpulan data yang sesuai guna memastikan integritas data. Data yang lebih lengkap meningkatkan deteksi ancaman.
// Callback inisialisasi. Mengembalikan kode status pemanggilan antarmuka. typedef void (^TTInitListener)(int); /** * Menginisialisasi SDK. * * @param appkey Kunci. * @param options Parameter opsional. * @param onInitFinish Callback saat inisialisasi selesai. * @return Menunjukkan apakah inisialisasi berhasil. */ - (int)init:(NSString *)appkey collectType:(TTCollectType)type options:(NSMutableDictionary *_Nullable)options listener:(TTInitListener _Nullable)onInitFinish;Parameter:
appkey: Tipe: NSString. Authentication key SDK Anda.
collectType: Tipe: TTCollectType. Mode pengumpulan data. Nilai yang valid:
Bidang
Deskripsi
Contoh
TT_DEFAULT
Mengumpulkan semua data.
TT_DEFAULT
TT_NO_BASIC_DATA
Tidak mengumpulkan data perangkat dasar.
Termasuk nama perangkat, versi OS, dan resolusi layar.
TT_NO_X | TT_NO_Y
(di mana X dan Y merepresentasikan jenis bidang data yang dikecualikan)
TT_NO_UNIQUE_DATA
Tidak mengumpulkan data identifier unik.
Termasuk IDFV dan IDFA.
TT_NO_EXTRA_DATA
Tidak mengumpulkan data perangkat yang diperluas.
Termasuk informasi Wi-Fi yang terhubung (SSID, BSSID) dan daftar jaringan Wi-Fi terdekat.
TT_NOT_GRANTED
Tidak mengumpulkan data privasi yang disebutkan sebelumnya.
TT_NOT_GRANTED
options: Tipe: NSMutableDictionary. Parameter opsional untuk pengumpulan data. Nilai default adalah nil. Parameter berikut tersedia:
Bidang
Deskripsi
Contoh
IPv6
Menentukan apakah akan menggunakan nama domain IPv6 untuk melaporkan informasi perangkat.
0 (default): Menggunakan nama domain IPv4.
1: Menggunakan nama domain IPv6.
1
Intl
Menentukan apakah akan menggunakan nama domain di luar Tiongkok daratan untuk melaporkan informasi perangkat.
0 (default): Melaporkan ke Tiongkok daratan.
1: Melaporkan ke wilayah di luar Tiongkok daratan.
1
CustomUrl
Menetapkan nama domain server pelaporan data.
https://cloudauth-device.us-west-1.aliyuncs.com
CustomHost
Menetapkan host server pelaporan data.
cloudauth-device.us-west-1.aliyuncs.com
CatatanUntuk sebagian besar situs internasional, cukup atur parameter Intl. Untuk melaporkan data ke situs tertentu, atur parameter CustomUrl dan CustomHost. Situs yang tersedia meliputi:
Jika
Intldiatur ke0, data dilaporkan ke situs default di Tiongkok (Shanghai): https://cloudauth-device.cn-shanghai.aliyuncs.comJika
Intldiatur ke1:Situs default adalah Singapura: https://cloudauth-device.ap-southeast-1.aliyuncs.com
Indonesia (Jakarta): https://cloudauth-device.ap-southeast-5.aliyuncs.com
AS (Silicon Valley): https://cloudauth-device.us-west-1.aliyuncs.com
Jerman (Frankfurt): https://cloudauth-device.eu-central-1.aliyuncs.com
Tiongkok (Hong Kong): https://cloudauth-device.cn-hongkong.aliyuncs.com
listener: Tipe: TTInitListener. Antarmuka callback inisialisasi SDK. Anda dapat menggunakan callback ini untuk menentukan status inisialisasi. Nilai default adalah nil.
TTCode
Kode
Deskripsi
TT_SUCCESS
0
Inisialisasi berhasil.
TT_NOT_INIT
-1
SDK belum diinisialisasi.
TT_NOT_PERMISSION
-2
Izin iOS yang diperlukan belum diberikan.
TT_UNKNOWN_ERROR
-3
Terjadi kesalahan sistem yang tidak diketahui.
TT_NETWORK_ERROR
-4
Terjadi kesalahan jaringan.
TT_NETWORK_ERROR_EMPTY
-5
Terjadi kesalahan jaringan. Konten yang dikembalikan adalah string kosong.
TT_NETWORK_ERROR_INVALID
-6
Format respons jaringan tidak valid.
TT_PARSE_SRV_CFG_ERROR
-7
Gagal mengurai konfigurasi server.
TT_NETWORK_RET_CODE_ERROR
-8
Gerbang mengembalikan respons kegagalan.
TT_APPKEY_EMPTY
-9
appkey kosong.
TT_PARAMS_ERROR
-10
Terjadi kesalahan parameter lainnya.
TT_FGKEY_ERROR
-11
Terjadi kesalahan perhitungan kunci.
TT_APPKEY_ERROR
-12
Versi SDK tidak cocok dengan versi appkey.
Nilai kembalian: Tipe: int. kode kesalahan.
0menunjukkan keberhasilan, dan angka negatif menunjukkan kegagalan.Contoh:
// appkey adalah kunci autentikasi yang diberikan kepada Anda di konsol Alibaba Cloud. NSString *appKey = @"xxxxxxxxxxxxxxxxxxxxx"; // Parameter opsional. Anda dapat mengonfigurasi IPv6 dan pelaporan dari luar Tiongkok daratan. NSMutableDictionary *options = [[NSMutableDictionary alloc] init]; [options setValue:@"0" forKey:@"IPv6"]; // Gunakan IPv4. [options setValue:@"0" forKey:@"Intl"]; // Laporkan data dari dalam Tiongkok daratan. // [options setValue:@"1" forKey:@"Intl"]; // Laporkan data dari luar Tiongkok daratan. // Laporkan data ke wilayah AS (Barat). // [options setValue:@"https://cloudauth-device.us-west-1.aliyuncs.com" forKey:@"CustomUrl"]; // [options setValue:@"cloudauth-device.us-west-1.aliyuncs.com" forKey:@"CustomHost"]; // Pemanggilan inisialisasi mengumpulkan informasi perangkat satu kali. Anda dapat memanggil fungsi init lagi untuk mengumpulkan informasi untuk skenario bisnis yang berbeda. // Pengumpulan data lengkap. if (0 == [[AliTigerTally sharedInstance] init:appkey collectType:TT_DEFAULT options:options listener:nil]) { NSLog(@"Inisialisasi berhasil"); } else { NSLog(@"Inisialisasi gagal"); } // Untuk mengumpulkan jenis data pribadi tertentu, gunakan operator "|" untuk menentukan beberapa jenis. TTCollectType collectPrivacy = TT_NO_BASIC_DATA | TT_NO_EXTRA_DATA; int ret = [[AliTigerTally sharedInstance] init:appkey collectType:collectPrivacy options:options listener:nil]; // Jangan kumpulkan data pribadi. int ret = [[AliTigerTally sharedInstance] init:appkey collectType:TT_NOT_GRANTED options:options listener:nil];
Hashing data.
Antarmuka penandatanganan kustom ini melakukan hashing terhadap data input untuk menghasilkan string
whash, yang berfungsi sebagai signature kustom. Untuk permintaan POST, PUT, dan PATCH, gunakan badan permintaan sebagai input. Untuk permintaan GET dan DELETE, gunakan URL lengkap. Anda juga harus menambahkan stringwhashyang dihasilkan ke bidang ali_sign_whash dalam Header permintaan HTTP.// Jenis permintaan: typedef NS_ENUM(NSInteger, TTRequestType) { TT_GET=0, TT_POST, TT_PUT, TT_PATCH, TT_DELETE }; /** * Melakukan hashing terhadap data signature kustom. * @param type Jenis data. * @param input Data yang akan ditandatangani. * @return String whash. */ - (NSString *)vmpHash:(TTRequestType)type input:(NSData *)input;Parameter:
type: Tipe: TTTypeRequest. Jenis data. Nilai yang valid:
GET: Data permintaan GET.
POST: Data permintaan POST.
PUT: Data permintaan PUT.
PATCH: Data permintaan PATCH.
DELETE: Data permintaan DELETE.
input: Tipe: NSData. Data yang akan ditandatangani. Masukkan badan atau URL berdasarkan type.
Nilai kembalian: Tipe: NSString. String
whash.Contoh:
// Permintaan GET NSString *url = @"https://tigertally.aliyun.com/apptest"; NSString *whash = [[AliTigerTally sharedInstance] vmpHash:TT_GET input:[url dataUsingEncoding:NSUTF8StringEncoding]]; NSLog(@"whash: %@", whash); // Permintaan POST NSString *body = @"hello world"; NSString *whash = [[AliTigerTally sharedInstance] vmpHash:TT_POST input:[body dataUsingEncoding:NSUTF8StringEncoding]]; NSLog(@"whash: %@", whash);
CatatanPemanggilan antarmuka ini hanya diperlukan jika Anda telah mengaktifkan opsi penandatanganan kustom di konsol WAF. Jika Anda menggunakan konfigurasi signature default, Anda dapat melewati langkah ini.
Penandatanganan data.
Metode ini menggunakan teknologi VMP untuk menandatangani data input dan mengembalikan sebuah string
wtokenuntuk otentikasi permintaan./** * Menandatangani data. * @param input Data yang akan ditandatangani. * @return string wtoken. */ - (NSString *)vmpSign:(NSData *)input;Parameter:
input: Tipe: NSData. Data yang akan ditandatangani. Biasanya berupa seluruh request body atau
whashdari custom signing.
Nilai kembalian: Tipe: NSString. String
wtoken.Contoh:
// Signature default yang dikonfigurasi di Konsol (custom signing tidak dipilih). NSString *body = @"hello world"; NSString *wtoken = [[AliTigerTally sharedInstance] vmpSign:[body dataUsingEncoding:NSUTF8StringEncoding]]; NSLog(@"wtoken: %@", wtoken); // Custom signing yang dikonfigurasi di Konsol. // Custom signing untuk permintaan POST. NSString *whash = [[AliTigerTally sharedInstance] vmpHash:TT_POST input:[body dataUsingEncoding:NSUTF8StringEncoding]]; NSString *wtoken = [[AliTigerTally sharedInstance] vmpSign:[whash dataUsingEncoding:NSUTF8StringEncoding]]; NSLog(@"whash: %@, wtoken: %@", whash, wtoken); // Custom signing untuk permintaan GET. NSString *url = @"https://tigertally.aliyun.com/apptest"; NSString *whash = [[AliTigerTally sharedInstance] vmpHash:TT_GET input:[url dataUsingEncoding:NSUTF8StringEncoding]]; NSString *wtoken = [[AliTigerTally sharedInstance] vmpSign:[whash dataUsingEncoding:NSUTF8StringEncoding]]; NSLog(@"whash: %@, wtoken: %@", whash, wtoken);CatatanSaat menggunakan custom signing, input untuk antarmuka vmpSign harus berupa string
whashyang dihasilkan oleh vmpHash. Saat Anda mengonfigurasi kebijakan berbasis skenario untuk App Protection, Anda harus mengatur Custom Signing Field menjadiali_sign_whash.Saat memanggil vmpHash untuk menghasilkan
whashuntuk permintaan GET, pastikan URL input identik dengan URL permintaan jaringan akhir. Perhatikan dengan cermat pengkodean URL, karena beberapa framework secara otomatis melakukan encode terhadap karakter atau parameter tertentu.Input untuk antarmuka vmpHash tidak boleh berupa array byte atau string kosong. Jika input berupa URL, URL tersebut harus mencakup path atau parameter.
Saat memanggil vmpSign, jika request body kosong (misalnya pada permintaan GET atau permintaan POST tanpa body), berikan
nilatau representasi NSData dari string kosong, seperti[@"" dataUsingEncoding:NSUTF8StringEncoding].Jika
whashatauwtokenmengembalikan salah satu string berikut, hal ini menunjukkan adanya kesalahan:you must call init first: Fungsi
initbelum dipanggil.you must input correct data: Data input tidak valid.
you must input correct type: Tipe input tidak valid.
3. Verifikasi sekunder
Periksa hasil.
Untuk menentukan apakah diperlukan verifikasi sekunder, periksa cookie dan badan dari tanggapan. Jika header berisi beberapa bidang Set-Cookie, gabungkan menjadi satu string cookie sebelum memanggil antarmuka ini.
/** * Memeriksa apakah perlu melakukan verifikasi sekunder. * * @param cookie Cookie tanggapan. * @param body Badan tanggapan. * @return 0: Lolos, 1: Diperlukan verifikasi sekunder. */ - (int)cptCheck:(NSString *)cookie body:(NSData *)body;Parameter:
cookie: Tipe: NSString. Semua cookie dalam tanggapan permintaan.
body: Tipe: NSData. Merupakan seluruh body dari tanggapan permintaan.
Nilai kembalian: Tipe: int. Hasil keputusan.
0menunjukkan permintaan lolos, dan1menunjukkan bahwa verifikasi sekunder diperlukan.Contoh:
NSString *cookie = @"key1=value1;key2=value2;"; NSData *body = xxx; int recheck = [[AliTigerTally sharedInstance] cptCheck:cookie body:body]; NSLog(@"recheck: %d", recheck);
Buat slider.
Jika hasil dari cptCheck menunjukkan perlunya verifikasi, buat objek slider. Objek TTCaptcha menyediakan metode
showdandismissuntuk mengontrol jendela slider. Gunakan TTOption untuk mengonfigurasi parameternya dan TTDelegate untuk menangani callback statusnya. Untuk menyesuaikan jendela slider, Anda harus menyediakan URL ke halaman kustom, yang dapat berupa file HTML lokal atau halaman remote./** * Menampilkan slider untuk verifikasi. * * @param view Komponen induk. * @param option Parameter. * @param detegate Protokol callback. */ - (TTCaptcha *)cptCreate:(UIView *)view option:(TTOption *)option delegate:(id<TTDelegate>)detegate; @protocol TTDelegate <NSObject> @required // Verifikasi slider berhasil. - (void)success:(TTCaptcha *)captcha data:(NSString *)data; // Verifikasi slider gagal. - (void)failed:(TTCaptcha *)captcha code:(NSString *)code; @end @interface TTOption : NSObject // Ketuk untuk membatalkan. @property (nonatomic, assign) BOOL cancelable; // Halaman kustom. @property (nonatomic, strong) NSString *customUri; // Bahasa. @property (nonatomic, strong) NSString *language; @end @interface TTCaptcha : NSObject - (instancetype)init:(UIView *)view option:(TTOption *)option delegate:(id<TTDelegate>)delegate; // Mendapatkan traceId slider untuk analitik data. - (NSString *)getTraceId; // Menampilkan slider. - (void)show; // Menutup slider. - (void)dismiss; @endParameter:
view: Tipe: View. Tampilan halaman saat ini.
option: Tipe: TTOption. Parameter konfigurasi slider.
delegate: Tipe: TTDelegate. Callback status slider.
Nilai kembalian: Tipe: TTCaptcha. Objek slider.
Contoh:
#pragma mark - TTDelegate - (void)failed:(TTCaptcha *)captcha code:(nonnull NSString *)code { NSLog(@"captcha gagal: %@", code); } - (void)success:(TTCaptcha *)captcha data:(nonnull NSString *)data { NSLog(@"captcha berhasil: %@", data); } TTOption *option = [[TTOption alloc] init]; // option.customUri = @"ali-tt-captcha-demo-ios"; option.language = @"cn"; option.cancelable = true; TTCaptcha *captcha = [[AliTigerTally sharedInstance] cptCreate:[self view] option:option delegate:self]; [captcha show];CatatanKesalahan "Verifikasi gagal" menunjukkan bahwa terdeteksi adanya anomali selama atau setelah interaksi pengguna dengan slider.
Tabel berikut menjelaskan kode kesalahan.
1001: Tantangan verifikasi gagal.
1002: Terjadi anomali sistem.
1003: Parameter yang ditentukan tidak valid.
1005: Verifikasi dibatalkan.
8001: Gagal menampilkan slider.
8002: Terjadi anomali pada data verifikasi slider.
8003: Terjadi anomali internal selama verifikasi slider.
8004: Terjadi kesalahan jaringan.
Praktik terbaik
#import "DemoController.h"
#if __has_include(<AliTigerTally_NOIDFA/AliTigerTally_NOIDFA.h>)
#import <AliTigerTally_NOIDFA/AliTigerTally_NOIDFA.h>
#else
#import <AliTigerTally_IDFA/AliTigerTally_IDFA.h>
#endif
@interface DemoController () <TTDelegate>
@end
static NSString *kAppHost = @"******";
static NSString *kAppUrl = @"******";
static NSString *kAppkey = @"******";
@implementation DemoController
- (void)viewDidLoad {
[super viewDidLoad];
// Lakukan pengaturan tambahan setelah memuat tampilan.
[self doTest];
}
- (void)doTest {
NSThread *thread = [[NSThread alloc] initWithBlock:^{
// Inisialisasi SDK.
NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
// [options setValue:@"1" forKey:@"Intl"]; // Konfigurasi untuk pelaporan internasional.
int code = [[AliTigerTally sharedInstance] init:kAppkey collectType:TT_DEFAULT options:options listener:nil];
NSLog(@"tigertally init: %d", code);
// Jangan lakukan panggilan sinkron segera.
[NSThread sleepForTimeInterval:2.0];
// Hasilkan signature.
NSString *body = @"hello world";
NSString *whash = nil, *wtoken = nil;
// Penandatanganan kustom.
whash = [[AliTigerTally sharedInstance] vmpHash:TT_Post input:[body dataUsingEncoding:NSUTF8StringEncoding]];
wtoken = [[AliTigerTally sharedInstance] vmpSign:[whash dataUsingEncoding:NSUTF8StringEncoding]];
NSLog(@"tigertally vmp: %@, %@", whash, wtoken);
// Penandatanganan default.
// wtoken = [[AliTigerTally sharedInstance] vmpSign:[body dataUsingEncoding:NSUTF8StringEncoding]];
// NSLog(@"tigertally vmp: %@", wtoken);
[self doPost:kAppUrl host:kAppHost whash:whash wtoken:wtoken body:[body dataUsingEncoding:NSUTF8StringEncoding] callback:^(NSInteger code, NSString* cookie, NSData *body) {
int check = [[AliTigerTally sharedInstance] cptCheck:cookie body:body];
NSLog(@"hasil captcha:%d", check);
if (check == 0) return;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self doShow];
}];
}];
}];
[thread start];
}
- (void)doShow {
NSLog(@"captcha show");
TTOption *option = [[TTOption alloc] init];
// option.customUri = @"ali-tt-captcha-demo-ios";
option.language = @"cn";
option.cancelable = true;
TTCaptcha *captcha = [[AliTigerTally sharedInstance] cptCreate:[self view] option:option delegate:self];
[captcha show];
}
- (void)doPost:(NSString *)url host:(NSString *)host whash:(NSString *)whash wtoken:(NSString *)wtoken body:(NSData *)body callback:(void(^)(NSInteger code, NSString* cookie, NSData *body))callback {
NSLog(@"mulai reqeust post");
NSURL* requestUrl = [NSURL URLWithString: url];
NSData* requestBody = body;
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:requestUrl cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
[request setValue: @"text/x-markdown" forHTTPHeaderField: @"Content-Type"];
[request setValue: host forHTTPHeaderField: @"HOST"];
[request setValue: wtoken forHTTPHeaderField:@"wToken"];
if (whash) {
[request setValue:whash forHTTPHeaderField:@"ali_sign_whash"];
}
request.HTTPMethod = @"post";
request.HTTPBody = requestBody;
NSURLSessionDataTask* dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
NSLog(@"tiger tally sign gagal: %@", [error description]);
callback(-1, nil, [[error description] dataUsingEncoding:NSUTF8StringEncoding]);
return;
}
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*) response;
NSInteger code = httpResponse.statusCode;
NSString* body = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSMutableString* cookies = [[NSMutableString alloc] init];
for (NSHTTPCookie* cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
if ([url containsString:[cookie domain]]) {
NSLog(@"domain:%@, path: %@, name:%@, value: %@", [cookie domain], [cookie path], [cookie name], [cookie value]);
[cookies appendFormat: @"%@=%@;", [cookie name], [cookie value]];
}
}
NSLog(@"kode respons: %ld", code);
NSLog(@"cookie respons: %@", cookies);
NSLog(@"badan respons: %@", body ? (body.length > 100 ? [body substringToIndex:100]:body) : @"");
callback(code, cookies, data);
}];
[dataTask resume];
}
#pragma mark - TTDelegate
- (void)failed:(TTCaptcha *)captcha code:(nonnull NSString *)code {
NSLog(@"captcha gagal: %@", code);
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:code preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:alert animated:true completion:nil];
}
- (void)success:(TTCaptcha *)captcha data:(nonnull NSString *)data {
NSLog(@"captcha berhasil: %@", data);
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:data preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:alert animated:true completion:nil];
}
@end