Untuk mengonfigurasi aturan berbasis skenario anti-crawler pada Bot Management di Konsol, Anda harus mengintegrasikan WAF App Protection SDK. Topik ini menjelaskan cara mengintegrasikan SDK ke dalam aplikasi Android.
Latar Belakang
App Protection SDK menandatangani permintaan dari klien aplikasi. Server Web Application Firewall (WAF) memverifikasi tanda tangan tersebut untuk mengidentifikasi risiko, memblokir Permintaan Serangan, dan melindungi aplikasi.
Batasan
-
Untuk Android, SDK mendukung arsitektur arm64-v8a dan armeabi-v7a.
-
Level API Android harus 16 atau lebih tinggi.
-
Metode init dapat memakan waktu. Untuk memastikan perlindungan penuh, tunggu minimal 2 detik antara pemanggilan metode init dan metode vmpSign. Penundaan ini direkomendasikan demi perlindungan optimal, meskipun tidak wajib. Anda dapat menyesuaikan penundaan sesuai kebutuhan bisnis, namun penundaan yang lebih singkat berpotensi mengurangi efektivitas fitur keamanan.
-
Saat menggunakan ProGuard untuk obfuscasi kode, gunakan opsi -keep untuk mempertahankan metode SDK. Contohnya:
-keep class com.aliyun.TigerTally.** {*;} -keep class com.aliyun.captcha.* {*;} -keepclassmembers,allowobfuscation class * { @com.alibaba.fastjson.annotation.JSONField <fields>; } -keep class com.alibaba.fastjson.** {*;}
Prasyarat
-
Dapatkan SDK untuk aplikasi Android Anda.
Untuk mendapatkan SDK, ajukan ticket kepada ahli teknis produk kami.
CatatanSDK Android mencakup dua file AAR: AliTigerTally_X.Y.Z.aar dan AliCaptcha_X.Y.Z.aar, dengan X.Y.Z sebagai nomor versi.
Anda telah memperoleh authentication key SDK (juga dikenal sebagai appkey).
Setelah Anda mengaktifkan Bot Management, buka halaman . Di daftar aplikasi, klik Obtain and Copy AppKey untuk mendapatkan authentication key SDK. Kunci ini diperlukan untuk initialization SDK dan harus disertakan dalam kode integrasi Anda.
CatatanSetiap Akun Alibaba Cloud memiliki appkey unik untuk semua domain names 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 Android Studio, ikuti wizard konfigurasi untuk membuat proyek Android baru. Struktur direktori proyek ditunjukkan pada gambar berikut.

Langkah 2: Integrasikan AAR
-
Ekstrak file SDK tigertally-X.Y.Z-xxxxxx-android.tgz, lalu salin semua file AAR dari folder hasil ekstraksi ke direktori libs modul utama Anda (jalur pastinya tergantung pada konfigurasi proyek Anda).

-
Buka file build.gradle aplikasi Anda dan tambahkan dependensi pada AliTigerTally_X.Y.Z.aar dan AliCaptcha_X.Y.Z.aar dari direktori
libs.PentingGanti X.Y.Z dalam nama file AliTigerTally_X.Y.Z.aar dan AliCaptcha_X.Y.Z.aar dengan nomor versi file AAR Anda.
Konfigurasinya sebagai berikut:
dependencies { // ... implementation files('libs/AliTigerTally_X.Y.Z.aar') implementation files('libs/AliCaptcha_X.Y.Z.aar') // dependensi library pihak ketiga implementation 'com.alibaba:fastjson:1.2.83_noneautotype' implementation 'com.squareup.okhttp3:okhttp:3.11.0' implementation 'com.squareup.okio:okio:1.14.0' }
Langkah 3: Filter arsitektur CPU SO
Jika proyek Anda belum menggunakan file SO, tambahkan konfigurasi berikut ke file build.gradle Anda.
android {
defaultConfig {
ndk {
abiFilters 'arm64-v8a', 'armeabi-v7a'
}
}
}
Langkah 4: Minta izin
-
Izin wajib
<uses-permission android:name="android.permission.INTERNET"/> -
Izin opsional
<uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Untuk Android 6.0 dan versi setelahnya, Anda harus meminta izin android.permission.READ_EXTERNAL_STORAGE dan android.permission.WRITE_EXTERNAL_STORAGE secara dinamis.
Langkah 5: Tambahkan kode integrasi
1. Tambahkan file header
import com.alibaba.fastjson.*;
import com.aliyun.tigertally.*;
2. Siapkan penandatanganan data
-
Tetapkan ID kustom untuk setiap pengguna akhir. Hal ini memungkinkan Anda mengonfigurasi kebijakan mitigasi WAF secara lebih fleksibel.
/** * Menetapkan akun pengguna. * * @param account Akun pengguna. * @return Kode kesalahan. */ public static int setAccount(String account)-
Parameter:
-
account: String. String yang mengidentifikasi pengguna. Kami merekomendasikan penggunaan format yang telah didesensitisasi.
-
-
Nilai kembalian: int. Mengembalikan 0 jika berhasil, atau -1 jika gagal.
-
Kode contoh:
// Untuk tamu, Anda dapat melewatkan setAccount dan langsung menginisialisasi SDK. Setelah pengguna login, panggil setAccount dan inisialisasi ulang. String account = "user001"; TigerTallyAPI.setAccount(account);
-
-
Inisialisasi SDK dan lakukan pengumpulan data awal.
Pengumpulan data awal mengumpulkan informasi perangkat satu kali. Anda dapat memanggil fungsi
initlagi untuk melakukan pengumpulan baru sesuai kebutuhan bisnis Anda. Tersedia tiga mode pengumpulan: pengumpulan lengkap, pengumpulan privasi kustom, dan pengumpulan non-privasi. Mode non-privasi tidak mengumpulkan data dari bidang yang terkait privasi pengguna akhir, termasuk: imei, imsi, simSerial, wifiMac, wifiList, bluetoothMac, dan androidId.CatatanPilih mode pengumpulan yang sesuai dengan persyaratan kepatuhan Anda dan pastikan integritas data. Data lengkap meningkatkan identifikasi risiko.
// Callback inisialisasi public interface TTInitListener { // Parameter code menunjukkan kode status pemanggilan antarmuka. void onInitFinish(int code); } /** * Menginisialisasi SDK dengan callback. * * @param context Konteks aplikasi. * @param appkey Appkey SDK. * @param collectType Mode pengumpulan data. * @param otherOptions Parameter opsional. * @param listener Callback inisialisasi. * @return Kode kesalahan. */ public static int init(Context context, String appkey, int collectType, Map<String, String> otherOptions, TTInitListener listener);-
Parameter:
-
context: Context. Konteks aplikasi Anda.
-
appkey: String. Appkey SDK Anda.
-
collectType: int. Mode pengumpulan. Nilai valid:
Parameter
Deskripsi
Contoh
TT_DEFAULT
Mengumpulkan semua data.
TigerTallyAPI.TT_DEFAULT
TT_NO_BASIC_DATA
Tidak mengumpulkan data perangkat dasar.
Mencakup: Nama perangkat (Build.DEVICE), versi Android (Build.VERSION#RELEASE), dan resolusi layar.
TigerTallyAPI.X | TigerTallyAPI.Y
(Menunjukkan bahwa baik X maupun Y tidak dikumpulkan. X dan Y merepresentasikan nama bidang item tertentu.)
TT_NO_IDENTIFY_DATA
Tidak mengumpulkan data pengenal perangkat.
Mencakup: IMEI, IMSI, SimSerial, BuildSerial (SN), dan alamat MAC.
TT_NO_UNIQUE_DATA
Tidak mengumpulkan data pengenal unik.
Mencakup: OAID, Google Advertising ID, dan Android ID.
TT_NO_EXTRA_DATA
Tidak mengumpulkan data perangkat tambahan.
Mencakup: daftar aplikasi berbahaya/abu-abu, IP LAN, IP DNS, informasi Wi-Fi terhubung (SSID, BSSID), daftar Wi-Fi terdekat, informasi lokasi, dan informasi sensor.
TT_NOT_GRANTED
Tidak mengumpulkan data privasi apa pun yang disebutkan sebelumnya.
TigerTallyAPI.TT_NOT_GRANTED
-
otherOptions: Map<String, String>. Parameter opsional untuk pengumpulan data. Dapat bernilai null. Parameter yang tersedia:
Parameter
Deskripsi
Contoh
IPv6
Menentukan apakah akan menggunakan nama domain IPv6 untuk melaporkan informasi perangkat.
-
0 (default): Gunakan nama domain IPv4.
-
1: Gunakan nama domain IPv6.
1
Intl
Menentukan apakah akan melaporkan informasi perangkat ke wilayah luar Tiongkok daratan.
-
0 (default): Laporkan ke Tiongkok daratan.
-
1: Laporkan ke wilayah luar Tiongkok daratan.
1
CustomUrl
Nama domain server pelaporan data.
https://cloudauth-device.us-west-1.aliyuncs.com
CustomHost
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.com -
Jika
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: TTInitListener. Callback inisialisasi SDK. Gunakan callback ini untuk memeriksa status inisialisasi. Dapat bernilai null.
TTCode
Kode
Deskripsi
TT_SUCCESS
0
SDK berhasil diinisialisasi.
TT_NOT_INIT
-1
SDK belum diinisialisasi.
TT_NOT_PERMISSION
-2
SDK belum diberikan izin Android yang diperlukan.
TT_UNKNOWN_ERROR
-3
Kesalahan sistem tidak dikenal.
TT_NETWORK_ERROR
-4
Kesalahan jaringan.
TT_NETWORK_ERROR_EMPTY
-5
Kesalahan jaringan: respons 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
Gateway mengembalikan respons kegagalan.
TT_APPKEY_EMPTY
-9
Appkey kosong.
TT_PARAMS_ERROR
-10
Parameter tidak valid.
TT_FGKEY_ERROR
-11
Kesalahan perhitungan kunci.
TT_APPKEY_ERROR
-12
Ketidakcocokan antara versi SDK dan appkey.
-
-
Nilai kembalian: int. Mengembalikan 0 jika berhasil, atau -1 jika gagal.
-
Kode contoh:
// Appkey adalah kunci autentikasi yang diberikan di platform Alibaba Cloud. final String appkey="******"; // Parameter opsional untuk mengonfigurasi IPv6 dan pelaporan internasional. Map<String, String> options = new HashMap<>(); options.put("IPv6", "0"); // Gunakan IPv4. options.put("Intl", "0"); // Laporkan ke Tiongkok daratan. //options.put("Intl", "1"); // Laporkan ke wilayah luar Tiongkok daratan. // Laporkan ke AS (Silicon Valley). //options.put("CustomUrl", "https://cloudauth-device.us-west-1.aliyuncs.com"); //options.put("CustomHost", "cloudauth-device.us-west-1.aliyuncs.com"); // Pengumpulan data awal mengumpulkan informasi perangkat satu kali. Anda dapat memanggil fungsi init lagi untuk melakukan pengumpulan baru sesuai kebutuhan bisnis Anda. // Pengumpulan lengkap. int ret = TigerTallyAPI.init(this.getApplicationContext(), appkey, TigerTallyAPI.TT_DEFAULT, options, null); // Tentukan data privasi yang akan dikumpulkan. Anda dapat menggabungkan flag berbeda dengan operator "|". int privacyFlag = TigerTallyAPI.TT_NO_BASIC_DATA | TigerTallyAPI.TT_NO_UNIQUE_DATA; int ret = TigerTallyAPI.init(this.getApplicationContext(), appkey, privacyFlag, options, null); // Jangan kumpulkan bidang privasi. int ret = TigerTallyAPI.init(this.getApplicationContext(), appkey, TigerTallyAPI.TT_NOT_GRANTED, options, null); Log.d("AliSDK", "ret:" + ret);
-
-
Hash data.
Metode penandatanganan kustom ini menghitung hash dari data masukan dan mengembalikan string
whashyang dihasilkan sebagai data tanda tangan kustom. Untuk permintaan POST, PUT, dan PATCH, berikan request body. Untuk permintaan GET dan DELETE, berikan URL lengkap. Stringwhashharus ditambahkan ke bidang ali_sign_whash dalam Header permintaan HTTP.// Jenis permintaan: public enum RequestType { GET, POST, PUT, PATCH, DELETE } /** * Hash data untuk tanda tangan kustom. * * @param type Jenis permintaan. * @param input Data yang akan di-hash. * @return String whash. */ public static String vmpHash(RequestType type, byte[] input);-
Parameter:
-
type: RequestType. Jenis permintaan. Nilai valid:
-
GET: Permintaan GET.
-
POST: Permintaan POST.
-
PUT: Permintaan PUT.
-
PATCH: Permintaan PATCH.
-
DELETE: Permintaan DELETE.
-
-
input: byte[]. Data yang akan di-hash.
-
Nilai kembalian: String. Mengembalikan string
whash. -
Kode contoh:
// Permintaan GET String url = "https://tigertally.aliyun.com/apptest"; String whash = TigerTallyAPI.vmpHash(TigerTallyAPI.RequestType.GET, url.getBytes()); Log.d("AliSDK", "whash:" + whash); // Permintaan POST String body = "hello world"; String whash = TigerTallyAPI.vmpHash(TigerTallyAPI.RequestType.POST, body.getBytes()); Log.d("AliSDK", "whash:" + whash);CatatanMetode ini tidak diperlukan untuk penandatanganan default. Untuk penandatanganan kustom, panggil metode ini untuk meng-hash data sebelum menandatangani.
-
-
Tandatangani data.
Metode ini menggunakan teknologi VMP untuk menandatangani data masukan dan mengembalikan string
wtokenuntuk otentikasi permintaan./** * Menandatangani data. * * @param type Jenis tanda tangan. * @param input Data yang akan ditandatangani. * @return String wtoken. */ public static String vmpSign(int type, byte[] input);-
Parameter:
-
type: int. Jenis penandatanganan data. Nilainya harus 1.
-
input: byte[]. Data yang akan ditandatangani. Biasanya merupakan seluruh request body atau string whash dari penandatanganan kustom.
-
-
Nilai kembalian: String. Mengembalikan string
wtoken. -
Kode contoh:
// Gunakan kode ini jika penandatanganan default dikonfigurasi di Konsol (penandatanganan kustom tidak dipilih). String body = "i am the request body, encrypted or not!"; String wtoken = TigerTallyAPI.vmpSign(1, body.getBytes("UTF-8")); Log.d("AliSDK", "wToken:" + wtoken); // Gunakan kode ini jika penandatanganan kustom dikonfigurasi di Konsol. // Permintaan GET String url = "https://tigertally.aliyun.com/apptest"; String whash = TigerTallyAPI.vmpHash(TigerTallyAPI.RequestType.GET, url.getBytes()); String wtoken = TigerTallyAPI.vmpSign(1, whash.getBytes()); Log.d("AliSDK", "whash:" + whash + ", wtoken:" + wtoken); // Permintaan POST String body = "hello world"; String whash = TigerTallyAPI.vmpHash(TigerTallyAPI.RequestType.POST, body.getBytes()); String wtoken = TigerTallyAPI.vmpSign(1, whash.getBytes()); Log.d("AliSDK", "whash:" + whash + ", wtoken:" + wtoken);Catatan-
Saat Anda memanggil vmpHash untuk penandatanganan kustom, parameter input metode vmpSign adalah string
whashyang dihasilkan. Saat mengonfigurasi kebijakan anti-bot aplikasi, nilai Custom Signature Field harus diatur keali_sign_whash. -
Saat Anda memanggil vmpHash untuk menghasilkan string
whashuntuk permintaan GET, pastikan URL input identik dengan URL akhir yang digunakan dalam permintaan jaringan. Perhatikan khusus encoding URL, karena beberapa framework secara otomatis meng-encode karakter Tionghoa atau parameter. -
Parameter input metode vmpHash tidak mendukung array byte kosong atau string kosong. Jika input berupa URL, URL tersebut harus berisi path atau parameter.
-
Saat Anda memanggil vmpSign, jika badan permintaan kosong (misalnya, dalam permintaan GET atau permintaan POST dengan badan kosong), berikan objek null atau nilai byte dari string kosong, seperti "".getBytes("UTF-8").
-
Jika nilai
whashatauwtokenadalah salah satu string berikut, SDK telah mengembalikan kesalahan:-
you must call init first: SDK belum diinisialisasi. Panggil
init()terlebih dahulu. -
you must input correct data: Data input tidak valid.
-
you must input correct type: Jenis input tidak valid.
-
-
-
3. Lakukan verifikasi sekunder
-
Evaluasi hasil.
Periksa bidang cookie dan body dalam respons untuk menentukan apakah verifikasi sekunder diperlukan. Sebelum memanggil metode ini, gabungkan beberapa entri Set-Cookie menjadi satu string cookie.
/** * Menentukan apakah perlu melakukan verifikasi sekunder. * * @param cookie String cookie. * @param body String body. * @return 0 untuk lolos, atau 1 jika verifikasi sekunder diperlukan. */ public static int cptCheck(String cookie, String body)-
Parameter:
-
cookie: String. Semua cookies dari respons HTTP.
-
body: String. Seluruh body dari respons HTTP.
-
-
Nilai kembalian: int. Mengembalikan 0 jika permintaan lolos, atau 1 jika verifikasi sekunder diperlukan.
-
Kode contoh:
String cookie = "key1=value1;kye2=value2;"; String body = "...."; int recheck = TigerTallyAPI.cptCheck(cookie, body); Log.d("AliSDK", "recheck:" + recheck);
-
-
Buat slider.
Jika cptCheck mengembalikan 1, buat objek slider. Objek TTCaptcha menyediakan metode
show()dandismiss()untuk menampilkan dan menyembunyikan jendela slider. TTOption mengenkapsulasi parameter yang dapat dikonfigurasi untuk slider, dan TTListener menyediakan callback untuk status sukses dan gagal. Untuk menggunakan jendela slider kustom, berikan URL halaman kustom. File HTML lokal dan halaman remote didukung./** * Membuat objek slider. * * @param activity Aktivitas tempat slider ditampilkan. * @param option Parameter slider. * @param listener Callback untuk slider. * @return Objek verifikasi slider. */ public static TTCaptcha cptCreate(Activity activity, TTOption option, TTListener listener); /** * Objek slider. */ public class TTCaptcha { /** * Menampilkan slider. */ public void show(); /** * Menyembunyikan slider. */ public void dismiss(); /** * Mendapatkan traceId slider untuk statistik data. */ public String getTraceId(); } /** * Parameter slider. */ public static class TTOption { // Menentukan apakah slider dapat ditutup dengan mengklik area kosong. public boolean cancelable; // Halaman kustom. File HTML lokal dan URL remote didukung. public String customUri; // Bahasa. public String language; } /** * Callback untuk event slider. */ public interface TTListener { /** * Dipanggil saat verifikasi berhasil. * * @param captcha Objek slider. * @param data Token. Default-nya adalah certifyId. */ void success(TTCaptcha captcha, String data); /** * Dipanggil saat verifikasi gagal. * * @param captcha Objek slider. * @param code Kode kesalahan. */ void failed(TTCaptcha captcha, String code); }-
Parameter:
-
activity: Activity. Aktivitas halaman saat ini.
-
option: TTOption. Parameter konfigurasi slider.
-
listener: TTListener. Callback status slider.
-
-
Nilai kembalian: TTCaptcha. Objek slider.
-
Kode contoh:
TTCaptcha.TTOption option = new TTCaptcha.TTOption(); // option.customUri = "file:///android_asset/ali-tt-captcha-demo.html"; option.language = "cn"; option.cancelable = false; TTCaptcha captcha = TigerTallyAPI.cptCreate(this, option, new TTCaptcha.TTListener() { @Override public void success(TTCaptcha captcha, String data) { Log.d(TAG, "captcha check success:" + data); } @Override public void failed(TTCaptcha captcha, String code) { Log.d(TAG, "captcha check failed:" + code); } }); captcha.show();CatatanKegagalan verifikasi menunjukkan bahwa anomali terdeteksi setelah pengguna menyelesaikan tantangan slider.
Daftar berikut menjelaskan kode kesalahan:
-
1001: Verifikasi gagal.
-
1002: Pengecualian sistem.
-
1003: Parameter tidak valid.
-
1005: Verifikasi dibatalkan.
-
8001: Gagal menampilkan slider.
-
8002: Data verifikasi slider abnormal.
-
8003: Pengecualian internal verifikasi slider.
-
8004: Kesalahan jaringan.
-
Contoh praktik terbaik
package com.aliyun.tigertally.apk;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.aliyun.TigerTally.TigerTallyAPI;
import com.aliyun.TigerTally.captcha.api.TTCaptcha;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class DemoActivity extends AppCompatActivity {
private final static String TAG = "TigerTally-Demo";
private final static String APP_HOST = "******";
private final static String APP_URL = "******";
private final static String APP_KEY = "******";
private final static OkHttpClient okHttpClient = new OkHttpClient();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
doTest();
}
private void doTest() {
Log.d(TAG, "captcha flow");
new Thread(() -> {
// Inisialisasi SDK.
Map<String, String> options = new HashMap<>();
//options.put("Intl", "1"); // Untuk mengaktifkan pelaporan internasional.
// Gunakan mode pengumpulan data lengkap.
int ret = TigerTallyAPI.init(this, APP_KEY, TigerTallyAPI.TT_DEFAULT, options, null);
// Atau, jangan kumpulkan bidang privasi.
// int ret = TigerTallyAPI.init(this, APP_KEY, TigerTallyAPI.TT_NOT_GRANTED, null, null);
Log.d(TAG, "tiger tally init: " + ret);
// Tunggu hingga inisialisasi selesai.
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Tandatangani data.
String data = "hello world";
String whash = null, wtoken = null;
// Gunakan penandatanganan kustom.
whash = TigerTallyAPI.vmpHash(TigerTallyAPI.RequestType.POST, data.getBytes());
wtoken = TigerTallyAPI.vmpSign(1, whash.getBytes());
Log.d(TAG, "tiger tally vmp: " + whash + ", " + wtoken);
// Gunakan penandatanganan standar.
// wtoken = TigerTallyAPI.vmpSign(1, data.getBytes());
// Log.d(TAG, "tiger tally vmp: " + wtoken);
// Kirim permintaan.
doPost(APP_URL, APP_HOST, whash, wtoken, data, (code, cookie, body) -> {
// Periksa apakah slider diperlukan.
int recheck = TigerTallyAPI.cptCheck(cookie, body);
Log.d(TAG, "captcha check result: " + recheck);
if (recheck == 0) return;
this.runOnUiThread(this::doShow);
});
}).start();
}
// Tampilkan slider.
public void doShow() {
Log.d(TAG, "captcha show");
TTCaptcha.TTOption option = new TTCaptcha.TTOption();
// option.customUri = "file:///android_asset/ali-tt-captcha-demo.html";
option.language = "cn";
option.cancelable = false;
TTCaptcha captcha = TigerTallyAPI.cptCreate(this, option, new TTCaptcha.TTListener() {
@Override
public void success(TTCaptcha captcha, String data) {
Log.d(TAG, "captcha check success:" + data);
}
@Override
public void failed(TTCaptcha captcha, String code) {
Log.d(TAG, "captcha check failed:" + code);
}
});
captcha.show();
}
// Kirim permintaan.
public static void doPost(String url, String host, String whash, String wtoken, String body, Callback callback) {
Log.d(TAG, "start request post");
int responseCode = 0;
String responseBody = "";
StringBuilder responseCookie = new StringBuilder();
try {
Request.Builder builder = new Request.Builder()
.url(url)
.addHeader("wToken", wtoken)
.addHeader("Host", host)
.post(RequestBody.create(MediaType.parse("text/x-markdown"), body.getBytes()));
if (whash != null) {
builder.addHeader("ali_sign_whash", whash);
}
Response response = okHttpClient.newCall(builder.build()).execute();
responseCode = response.code();
responseBody = response.body() == null ? "" : response.body().string();
for (String item : response.headers("Set-Cookie")) {
responseCookie.append(item).append(";");
}
Log.d(TAG, "response code:" + responseCode);
Log.d(TAG, "response cookie:" + responseCookie);
Log.d(TAG, "response body:" + (responseBody.length() > 100 ? responseBody.substring(0, 100) : ""));
if (response.isSuccessful()) {
Log.d(TAG, "success: " + response.code() + ", " + response.message());
} else {
Log.e(TAG, "failed: " + response.code() + ", " + response.message());
}
response.close();
} catch (Exception e) {
e.printStackTrace();
responseCode = -1;
responseBody = e.toString();
} finally {
if (callback != null) {
callback.onResponse(responseCode, responseCookie.toString(), responseBody);
}
}
}
public interface Callback {
void onResponse(int code, String cookie, String body);
}
}