minifyEnabled di aplikasi Android merusak panggilan GoogleApi [duplikat]

Dec 16 2020

TLDR - Aplikasi Android mengalami masalah dengan Google API saat minifyEnabled benar.

Ada aplikasi Android yang menggunakan Google API untuk membuat acara dan pertemuan google. Saya menggunakan alat cukup standar untuk bekerja dengan orang-orang API - GoogleAuthorizationCodeFlow, com.google.api.services.calendar.Calendar, com.google.api.services.calendar.model.Event. Saya menggunakan "Aplikasi server web" dengan cara autentikasi daripada "Aplikasi yang diinstal" tanpa alasan yang baik tetapi faktanya saya sudah membuat yang pertama berfungsi. Semua berfungsi dengan baik dalam mode debug saya, tetapi ketika saya masuk ke mode rilis, masalah muncul.

  • GoogleClientSecretsmenjadi tidak dapat memproses secret.json console.developers.google.commemberi saya. File yang sama berfungsi dengan baik dalam mode debug, tetapi sekarang GoogleClientSecrets.getDetailsmengembalikan null. Fakta lucu - GoogleClientSecrets.toString/GoogleClientSecrets.toPrettyStringmenampilkan data dari file, tetapi tampaknya kehilangan semua file konfigurasi kutipan. Akhirnya diperbaiki (sekarang saya membuat rahasia langsung menggunakan clientId / clientSecret, tanpa file json), tetapi mengapa masalah muncul di tempat pertama?
  • setelah perbaikan itu, flow.newAuthorizationUrl().setRedirectUri(redirectUrl).build()berikan saya https://accounts.google.com/o/oauth2/authsebagai gantinya https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force&client_id=<myClientId>&redirect_uri=<myRedirect>&response_type=code&scope=https://www.googleapis.com/auth/calendar. Sebagian besar bagian "relatif" dilewati, meskipun redirectUrl dan clientId dibaca dan disimpan dengan benar - tetapi tidak ada jejaknya di Url. Ini diperbaiki dengan menambahkan -keep class com.google.api.client.googleapis.auth.oauth2.*ke saya proguard-rules.pro. Yang sudah tampak seperti solusi yang lebih banyak, daripada solusi nyata, tetapi segalanya menjadi lebih buruk nanti.
  • setelah perbaikan itu, ketika saya melakukannya
    Credential credential = getCredential(context);
    Calendar service = new Calendar.Builder(HTTP_TRANSPORT,
                            JSON_FACTORY,
                            credential)
                            .setApplicationName(APPLICATION_NAME)
                            .build();
    service.events().insert(calendarId, event)
                            .setConferenceDataVersion(1)
                            .setSupportsAttachments(true)
                            .execute();

dengan acara yang sangat bagus yang berfungsi dengan baik tanpa minifikasi, maka saya dapatkan

c.f.b.a.b.c.b: 404 Not Found
{
   "errors" : [ {
     "domain" : "global",
     "reason" : "notFound",
     "message" : "Not Found"
   } ],
   "code" : 404,
   "message" : "Not Found"
}

Ini bisa diperbaiki dengan -keep class com.google.api.services.calendar.* { *; }di myproguard-rules.pro

  • setelah perbaikan itu, upaya yang sama untuk memasukkan acara memberi saya
    W/System.err: java.lang.IllegalArgumentException: key creator
            at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:889)
            at com.google.api.client.json.JsonParser.parse(JsonParser.java:382)
            at com.google.api.client.json.JsonParser.parse(JsonParser.java:355)
            at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:87)
            at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:81)
            at com.google.api.client.http.HttpResponse.parseAs(HttpResponse.java:459)
            at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)

Setelah beberapa pengujian, saya perhatikan, bahwa semua hal di atas hanya muncul jika minifyEnabled benar. Dengan minifyEnabled false, semua berfungsi seperti pesona. Sejauh ini saya menemukan 3 solusi

  • minifyEnabled false. Saya agak suka file saya dikecilkan dalam rilis
  • dontobfuscatedan dontshrinkmasuk proguard-rules.pro. Membantu, tetapi mengurangi efek minifikasi.
  • keep class * { *; }masuk proguard-rules.pro. Membantu, tetapi mengurangi efek minifikasi.

Saya tidak percaya bahwa opsi standar seperti minifyEnabled akan merusak sesuatu seperti GoogleAuthorizationmelalui alat standar com.google.api.client.*dalam skala yang begitu besar. Saya percaya saya membuat beberapa kesalahan bodoh dan jelas. Jerami terakhir saya, untuk saat ini, adalah cara "Terinstal" dari "Aplikasi server web", tetapi saya tidak terlalu menaruh harapan besar di sini - jika itu adalah sumber utama masalah, mengapa itu berfungsi tanpa minifikasi ...

Mengapa perilaku yang dijelaskan bisa terjadi? Apa yang saya lakukan salah?

Jawaban

IvanGarza Dec 16 2020 at 00:22

Ini bukan praktik yang tidak biasa untuk menambahkan pengecualian aturan ke proguard-rules.profile Anda setiap kali Anda menemukan masalah dengan obfuscation dalam versi rilis Anda.

Bekerja dengan ProGuard sendiri merupakan keseluruhan topik, tetapi jangan berpikir bahwa menambahkan pengecualian ke alat obfuscation aplikasi Anda akan merusak keamanan aplikasi Anda atau yang lainnya. Beberapa API dan pola pengkodean hanya memerlukan beberapa pengecualian agar berfungsi dengan baik; misalnya kelas / model data, dan semua yang berasal dari lapisan JNI selalu perlu di-de-obfuscated.

Berikut artikel singkat tentang topik tersebut jika Anda masih belum yakin.