アプリにアンチクローラールールを設定する前に、anti-Bot SDKをアプリに統合する必要があります。 このトピックでは、Anti-Bot SDKをiOSアプリに統合する方法について説明します。 このトピックでは、Anti-Bot SDKをSDKと呼びます。
背景情報
SDKは、アプリクライアントから送信されるリクエストに署名するために使用されます。 WAFはリクエストシグネチャを検証して、悪意のあるリクエストを検出およびブロックします。
制限事項
SDKには、IDFA (Identifier for Advertising) と非IDFAの2つのバージョンがあります。 次のSDKファイルは、2つのバージョンで提供されます。
AliTigerTally_IDFA.framework
AliTigerTally_NOIDFA.framework
IDFAバージョンを使用する場合は、AliTigerTally_IDFA.frameworkをiOSアプリに統合することを推奨します。 非IDFAバージョンを使用する場合は、AliTigerTally_NOIDFA.frameworkをiOSアプリに統合することを推奨します。
初期化プロセスは、完了するまでに長い時間を必要とする。 初期化プロセスが完了する前にvmpSign関数を呼び出すことはできません。
iOSアプリはiOS 9.0以降で実行する必要があります。 そうしないと、SDKをアプリに統合できません。
前提条件
iOSアプリ用のSDKが取得されました。
iOSアプリ用のSDKを取得するには、
テクニカルサポートのための切符。SDK認証キー
appkey
を取得します。SDK認証キーを取得するには、ボット管理モジュールを有効にし、アプリのシナリオ固有の保護テンプレートを作成します。 [シナリオの設定] ステップで、[App SDK Integration] パラメーターの [AppKeyの取得とコピー] をクリックします。 SDK認証キーを使用してSDK初期化リクエストを送信することもできます。 キーは統合コードに含まれている必要があります。
説明各Alibaba Cloudアカウントは、一意の
appkey
を使用します。 appkeyは、WAFインスタンスのすべての保護ドメイン名に使用できます。appkey
を使用して、SDKをAndroidアプリまたはiOSアプリに統合できます。SDK認証キーのサンプル:
**** OpKLvM6zliu6KopyHIhmneb_**** u4ekci2W8i6F9vrgpEezqAzEzj2ANrVUhvAXMwYzgY_**** vc51aEQlRovkRoUhRlVsf4IzO9dZp6nN_**** Wz8pk2TDLuMo4pVIQvGaxH3vrsnSQiK ****
手順1: プロジェクトの作成
この例では、XcodeでiOSプロジェクトが作成されます。 次の図は、テストプロジェクトを示しています。
ステップ2: フレームワークをプロジェクトに統合
AliTigerTally_IDFA.frameworkまたはAliTigerTally_NOIDFA.frameworkをプロジェクトにドラッグします。
IDFAバージョン
非IDFAバージョン
手順3: プロジェクトに依存関係ライブラリを追加する
依存ライブラリ | IDFAバージョンに必要 | 非IDFAバージョンに必要 |
libc ++.tbd | 可 | 可 |
CoreTelephony.framework | 可 | 可 |
libresolv.9.tbd | 可 | 可 |
AdSupport.framework | 可 | 任意 |
手順4: その他のリンカーフラグ設定の変更
を追加します。-ObjCへのリンカフラグその他のリンカーフラグ設定します。
ステップ5: 統合コードの追加
1. ヘッダーファイルの追加
IDFAバージョン:
#import <AliTigerTally_IDFA/AliTigerTally.h>
非IDFAバージョン:
#import <AliTigerTally_NOIDFA/AliTigerTally.h>
Swiftを使用する場合は、作成したブリッジヘッダーファイルを [Objective-C bridging header] オプションに追加します。
2. リクエスト署名の設定
リクエストに含めるユーザーIDを指定します。 これにより、Web Application Firewall (WAF) 保護ポリシーをより効率的に構成できます。
パラメーター: account。ユーザーIDを指定します。 データ型: 文字列。 マスクされたユーザーIDを入力することを推奨します。
Returned value: 値またはvoidが返されません。
サンプルコード:
SDKを初期化し、1回限りの情報収集を実行します。
端末情報を再度収集する場合は、再度
initialize
関数を呼び出します。パラメーター: appkey。SDK認証キーを指定します。 データ型: 文字列。
戻り値: int型のエラーコードが返されます。 0の値は、初期化が成功したことを示します。 負の値は、初期化が失敗したことを示します。
サンプルコード:
署名するリクエストをハッシュします。
署名するリクエストをハッシュします。 whash文字列が生成され、返されます。 リクエストがPOST、PUT、またはPATCHリクエストの場合は、リクエスト本文を指定します。 リクエストがGETまたはDELETEリクエストの場合は、リクエストされたURLを指定します。 HTTPリクエストヘッダーのali_sign_whashフィールドにwhash文字列を追加します。
パラメーターの説明
type: リクエストデータのタイプを指定します。 データ型: TTTypeRequest。 有効な値:
GET: GETリクエスト。
POST: POSTリクエスト。
PUT: PUTリクエスト。
PATCH: PATCHリクエスト。
DELETE: DELETEリクエスト。
data: 署名するデータを指定します。 データ型: byte[] 配列。 typeパラメーターの値に基づいて、リクエスト本文またはリクエストされたURLを指定します。
戻り値: whash文字列が返されます。
サンプルコード:
リクエストに署名します。
vmpSign関数を呼び出してリクエストに署名します。 wtoken文字列が返されます。
パラメーター: input。署名するデータ、またはvmpHash関数によって返されるwhash文字列を指定します。 データ型: byte[] 配列。
戻り値: wtoken文字列が返されます。
サンプルコード:
/**
* ユーザーアカウントを指定します。
*
* @ paramアカウントユーザーアカウント情報。
* /
- (void)setAccount :( NSString *) アカウント;
// ゲストユーザーのユーザーIDを指定するためにsetAccount関数を呼び出す必要はありません。 initialize関数を直接呼び出して、SDKを初期化できます。 ログオンしているユーザーに対してのみsetAccount関数を呼び出し、次にinitialize関数を呼び出す必要があります。
[[AliTigerTally sharedInstance] setAccount:@ "testAccount"];
/**
* SDKを初期化します。
*
* @ param appkey秘密鍵。
* @ return初期化が成功したかどうかを示します。
* /
- (int)initialize :( NSString *)appkey;
// appkeyは、Alibaba Cloudによって割り当てられた認証キーです。
// SDKを初期化し、1回限りの端末情報収集を実行します。 端末情報を再度収集する場合は、initialize関数を再度呼び出します。
NSString * appKey = @ "xxxxxxxxxxxxxxxxxxx";
if (0 == [[[AliTigerTally sharedInstance] initialize:appKey]){
NSLog(@ "初期化は成功です。");
} else {
NSLog(@ "初期化に失敗しました。");
}
// リクエストタイプ:
typedef NS_ENUM(NSInteger, TTTypeRequest) {
TTTypeGet=0, TTTypePost, TTTypePut, TTTypePatch, TTTypeDelete
};
/**
* 署名するリクエストをハッシュします。
* @ paramタイプリクエストデータのタイプです。
* @ param input署名するデータです。
* @ return whash
* /
- (NSString *)vmpHash:(TTTypeRequest) タイプ入力:(NSData *) 入力;
// GETリクエスト
NSString * url = @ " https://tigertally.aliyun.com/apptest ";
NSString * whash = [[AliTigerTally sharedInstance] vmpHash:TTTypeGetデータ:[url dataUsingEncoding:NSUTF8StringEncoding]]];
NSString * wtoken = [[AliTigerTally sharedInstance] vmpSign:[whash dataUsingEncoding:NSUTF8StringEncoding]];
NSLog(@ "whash: %@, wtoken: % @", whash, wtoken);
// POSTリクエスト
NSString * body = @ "hello world";
NSString * whash = [[AliTigerTally sharedInstance] vmpHash:TTTypePostデータ:[body dataUsingEncoding:NSUTF8StringEncoding]]];
NSString * wtoken = [[AliTigerTally sharedInstance] vmpSign:[whash dataUsingEncoding:NSUTF8StringEncoding]];
NSLog(@ "whash: %@, wtoken: % @", whash, wtoken);
/**
* リクエストに署名します。
* @ param input署名するデータです。
* @ return wtoken
* /
- (NSString *)vmpSign :( NSData *) 入力;
NSString * body = @ "hello world";
NSString * wtoken = [[AliTigerTally sharedInstance] vmpSign:[body dataUsingEncoding:NSUTF8StringEncoding]]];
NSLog(@ "wtoken: % @", wtoken);
vmpSign関数のinputパラメーターの値がvmpHash関数によって返されるwhash文字列の場合、iOSアプリのアンチクローラールールを設定するときに、HTTPヘッダーフィールドをali_sign_whashに設定します。
vmpHash関数を呼び出すときに、typeパラメーターをGETに設定した場合、入力URLがGETリクエストのURLであることを確認します。 GETリクエストのURLが文字列にエンコードされている場合は、vmpHash関数のinputパラメーターにURLエンコードされた文字列を指定します。
vmpHash関数のinputパラメーターは、空のバイトまたは空の文字列をサポートしていません。 vmpHash関数のdataパラメーターにURLを指定する場合は、URLにパスまたはクエリパラメーターも指定する必要があります。
vmpSign関数を呼び出すときに、入力パラメーターをnullに設定するか、リクエスト本文が空の場合は空の文字列のBytes値に設定します。 空の文字列のバイト値を取得するには、".getBytes(" UTF-8 ") コマンドを実行します。
次のwhashまたはwtoken文字列のいずれかが返された場合、初期化中に例外が発生しました。
initialize関数は呼び出されません。
you must input correct data: 入力データが無効です。
you must input correct type: 入力データの型が無効です。
3. 2要素認証を実行するかどうかの判断
2要素認証を実行するかどうかを判断します。
レスポンスのcookieフィールドとbodyフィールドの値に基づいて、2要素認証を実行するかどうかを決定します。 複数の場合セット-クッキーヘッダーが存在する場合は、Set-Cookieヘッダーをマージした後に関数を呼び出します。クッキー形式を指定します。
パラメーターの説明
cookie: レスポンス内のすべてのcookieを指定します。 データ型: 文字列。
body: レスポンスですべてのbodyを指定します。 データ型: 文字列。
戻り値はINTEGERデータ型です。 有効な値: 0と1。 値0は、二要素認証が不要であることを示す。 値1は、2要素認証が必要であることを示す。
サンプルコード:
スライダーを作成します。
cptCheck関数によって返される結果に基づいて、スライダを作成するかどうかを決定します。 TTCaptchaオブジェクトには、スライダーウィンドウを表示または非表示にするShowメソッドとDismissメソッドがあります。 TTOptionは、設定できるスライダーのパラメーターをカプセル化します。 TTDelegateは、スライダーCAPTCHA検証の3つの状態のコールバック関数をカプセル化します。 カスタムスライダーページを指定する場合は、TTOptionでページのアドレスを指定する必要があります。 オンプレミスHTMLファイルまたはURLを指定できます。
パラメーターの説明
view: ページビューを指定します。 データ型: view。
option: スライダー設定パラメーターを指定します。 データ型: TTOption。
delegate: スライダーCAPTCHA検証の3つの状態のコールバック関数を指定します。 データ型: TTDelegate。
戻り値: スライダーが返されます。 データ型: TTCaptcha.
サンプルコード:
エラーコード: 検証が異常な場合、スライダーの読み込みに失敗しました。 検証が失敗した場合、要求は検証に合格しませんでした。
エラーコード
説明
1001
入力パラメーターが無効です。
1002
ネットワーク例外が発生しました。
1003
JavaScriptコールバックデータが異常です。
1004
WebViewはWebページの読み込みに失敗しました。
1005
返されたデータが異常です。
1100
スライダーウィンドウはユーザーによって閉じられます。
/**
* 2要素認証を実行するかどうかを判断します。
*
* @ paramクッキー応答クッキー
* @ paramボディ応答ボディ
* @ return 0: 2要素認証が不要であることを示します。 1: 2要素認証が必要であることを示します。
* /
- (int)cptCheck :( NSString *)cookie body :( NSString *)body;
NSString * cookie = @ "key1=value1;kye2=value2;";
NSString * body = "....";
int recheck = [[AliTigerTally sharedInstance] cptCheck:cookie body:body];
NSLog(@ "recheck: % d" 、再チェック);
/**
* スライダーCAPTCHA検証を表示します。
*
* @ paramビュー親コンポーネント。
* @ paramオプションパラメータ。
* @ param detegateコールバックデリゲート。
* /
- (TTCaptcha *)cptCreate :( UIView *) ビューオプション :( TTOption *) オプションデリゲート :( id<TTDelegate>)detegate;
# pragmaマークスライダーコールバックデリゲート。
@ protocol TTDelegate <NSObject>
@ 必須
// スライダーCAPTCHA検証が成功しました。
- (void)success :( TTCaptcha *)captchaデータ :( NSString *) データ;
// スライダーCAPTCHA検証に失敗しました。
- (void)failed :( TTCaptcha *)captchaコード :( NSString *) コード;
// スライダーCAPTCHA検証例外が発生しました。
- (void) エラー :( TTCaptcha *)captchaコード :( NSInteger) コードメッセージ :( NSString *) メッセージ;
@ end
# pragma markパラメーター。
@ インターフェイスTTOption: NSObject
// クリックしてスライダーCAPTCHA検証をキャンセルします。
@ プロパティ (非原子、割り当て) BOOLキャンセル可能;
// スライダーCAPTCHA検証によって返されるエラーコードを非表示にします。
@ property (非アトミック、アサイン) BOOL hideError;
// カスタムページ。
@ プロパティ (非原子、強い) NSString * customUri;
// プログラミング言語。
@ プロパティ (非原子、強い) NSString * language;
// WAFによってブロックされたリクエストのトレースID。
@ property (非アトミック、強い) NSString * traceId;
// スライダーのタイトル。 タイトルの長さは最大20文字です。
@ property (非アトミック、強力) NSString * titleText;
// スライダーの説明。 説明の長さは最大60文字です。
@ property (非アトミック, strong) NSString * descText;
// スライダーの色。 例: "#007FFF" 。
@ プロパティ (非原子、強い) NSString * slideColor;
// トレースIDを非表示にするかどうかを指定します。
@ プロパティ (非アトミック、割り当て) BOOL hideTraceId;
@ end
# pragmaマークスライダー。
@ interface TTCaptcha : NSObject
- (instancetype)init :( UIView *)view option:(TTOption *)option delegate:(id<TTDelegate>)delegate;
// データ統計のスライダートレースIDを取得します。
- (NSString *)getTraceId;
// スライダーを表示します。
- (void) ショー;
// スライダーを非表示にします。
-(無効) 却下;
@ end
#pragmaマーク-TTDelegate
- (void) エラー :( TTCaptcha *)captcha code :( NSInteger)code message :( nonnull NSString *)message {
NSLog(@ "captcha error: % ld、% @" 、コード、メッセージ);
}
- (void)failed :( TTCaptcha *)captcha code :( non null NSString *)code {
NSLog(@ "captcha failed: % @" 、コード);
}
- (void)success :( TTCaptcha *)captcha data :( non null NSString *)data {
NSLog(@ "captcha success: % @" 、データ);
[captcha dismiss];
}
TTOption * option = [[TTOption alloc] init];
// option.customUri = @ "ali-tt-captcha-demo";
// option.traceId = @ "4534534534adf433534534543";
option.titleText = @ "テストタイトル";
option.de scText = @ "テスト説明";
option.language = @ "cn";
option.ca ncelable = true;
option.hideError = true;
オプションslideColor = @ "#007FFF";
option.hideTraceId= true;
TTCaptcha * captcha = [[AliTigerTally sharedInstance] cptCreate:[self view] option:option delegate:self];
[captchaショー];
例:
#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
静的NSString * kAppHost = @ "******";
静的NSString * kAppUrl = @ "******";
静的NSString * kAppkey = @ "******";
@ implementation DemoController
- (void)viewDidLoad {
[スーパーviewDidLoad];
// ビューの読み込み後に追加のセットアップを行います。
[自己のdoTest];
}
- (void)doTest {
NSLog(@ "captcha flow");
NSThread * thread = [[NSThread alloc] initWithBlock :^{
// SDKを初期化します。
int code = [[AliTigerTally sharedInstance] initialize:kAppkey];
NSLog(@ "tigertally init: % d" 、コード);
// SDKの初期化が完了するまで待ちます。
[NSThread sleepForTimeInterval:2.0];
// リクエストに署名します。
NSString * body = @ "hello world";
NSString * whash = nil、* wtoken = nil;
// リクエストをハッシュして署名します。
whash = [[AliTigerTally sharedInstance] vmpHash:TTTypePost入力:[body dataUsingEncoding:NSUTF8StringEncoding]];
wtoken = [[AliTigerTally sharedInstance] vmpSign:[whash dataUsingEncoding:NSUTF8StringEncoding]];
NSLog(@ "tigertally vmp: %@, % @", whash, wtoken);
// リクエストをハッシュせずにリクエストに署名します。
// wtoken = [[AliTigerTally sharedInstance] vmpSign:[body dataUsingEncoding:NSUTF8StringEncoding]];
// NSLog(@ "tigertally vmp: % @", wtoken);
[self doPost:kAppUrl host:kAppHost whash:whash wtoken:wtoken body:body callback:^(NSInteger code, NSString * _Nonnull cookie, NSString * _Nonnull body) {
int check = [[AliTigerTally sharedInstance] cptCheck:cookie body:body];
NSLog(@ "captcha result:% d" 、チェック);
if (check == 0) return;
[[NSOperationQueue mainQueue] addOperationWithBlock :^{
[セルフdoShow];
}];
}];
}];
[スレッド開始];
}
- (void)doShow {
NSLog(@ "captcha show");
TTOption * option = [[TTOption alloc] init];
// option.customUri = @ "ali-tt-captcha-demo";
// option.traceId = "4534534534adf433534534543";
option.titleText = @ "テストタイトル";
option.de scText = @ "テスト説明";
option.language = @ "cn";
option.ca ncelable = true;
option.hideError = true;
オプションslideColor = @ "#007FFF";
TTCaptcha * captcha = [[AliTigerTally sharedInstance] cptCreate:[self view] option:option delegate:self];
[captchaショー];
}
- (void)doPost :( NSString *)url host :( NSString *)host whash :( NSString *)whash wtoken:(NSString *)wtoken body:(NSString *)body callback :( void(^)(NSInteger code, NSString * cookie, NSString * body)) {
NSLog(@ "start reqeust post");
NSURL * requestUrl = [NSURL URLWithString: url];
NSData * requestBody = [body dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:requestUrl cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
[リクエストsetValue: @ "text/x-markdown" forHTTPHeaderField: @ "Content-Type"];
[リクエストsetValue: host forHTTPHeaderField: @ "HOST"];
[リクエストsetValue: wtoken forHTTPHeaderField:@ "wToken"];
if (whash) {
[リクエストsetValue:whash forHTTPHeaderField:@ "ali_sign_whash"];
}
request.HTTPMethod = @ "post";
request.HTTPBody = requestBody;
NSURLSessionDataTask * dataTask = [[NSURLSessionsharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
NSLog(@ "tiger talline sign failed: % @", [エラーの説明]);
コールバック (-1, nil, [エラーの説明]);
return;
}
NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *) response;
NSInteger code = httpResponse.statusCode;
NSString * body = [[NSString alloc] initWithData: データエンコード: NSUTF8StringEncoding];
NSMutableString * cookies = [[NSMutableString alloc] init];
for ([[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies] のNSHTTPCookie * cookie) {
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(@ "reponse code: % ld" 、code);
NSLog(@ "reponse cookie: % @" 、cookies);
NSLog(@ "reponse body: % @" 、body? (body.length > 100? [body substringToIndex:100]:body) : @ "");
コールバック (コード、クッキー、本文);
}];
[dataTask resume];
}
# プラグママーク-TTDelegate
- (void) エラー :( TTCaptcha *)captcha code :( NSInteger)code message :( nonnull NSString *)message {
NSLog(@ "captcha error: % ld、% @" 、コード、メッセージ);
}
- (void)failed :( TTCaptcha *)captcha code :( non null NSString *)code {
NSLog(@ "captcha failed: % @" 、コード);
}
- (void)success :( TTCaptcha *)captcha data :( non null NSString *)data {
NSLog(@ "captcha success: % @" 、データ);
[captcha dismiss];
UIAlertController * alert = [UIAlertController alertControllerWithTitle:nil message:data preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@ "Confirm" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:alert animated:true completion:nil];
}
@ end