minifyEnabled trong ứng dụng Android ngắt các cuộc gọi GoogleApi [trùng lặp]

Dec 16 2020

TLDR - Ứng dụng Android gặp sự cố với Google API khi minifyEnabled là true.

Có một ứng dụng Android sử dụng API Google để tạo sự kiện và cuộc họp trên google. Tôi sử dụng công cụ khá chuẩn để làm việc với những API - GoogleAuthorizationCodeFlow, com.google.api.services.calendar.Calendar, com.google.api.services.calendar.model.Event. Tôi đang sử dụng cách xác thực "Ứng dụng máy chủ web" thay vì "Ứng dụng đã cài đặt" mà không có lý do chính đáng nhưng thực tế là tôi đã làm cho ứng dụng đầu tiên hoạt động. Tất cả đều hoạt động tốt ở chế độ gỡ lỗi của tôi, nhưng khi tôi chuyển sang chế độ phát hành, vấn đề phát sinh.

  • GoogleClientSecretskhông thể xử lý bí mật.json console.developers.google.comđã cho tôi. Tệp tương tự hoạt động tốt trong chế độ gỡ lỗi, nhưng bây giờ GoogleClientSecrets.getDetailstrả về null. Sự thật thú vị - GoogleClientSecrets.toString/GoogleClientSecrets.toPrettyStringhiển thị dữ liệu từ tệp, nhưng nó dường như bị thiếu tất cả các tệp cấu hình trích dẫn có. Cuối cùng nó đã được sửa (bây giờ tôi đang tạo bí mật trực tiếp bằng clientId / clientSecret, không có tệp json), nhưng tại sao vấn đề lại xuất hiện ở vị trí đầu tiên?
  • sau khi sửa chữa đó, flow.newAuthorizationUrl().setRedirectUri(redirectUrl).build()cung cấp cho tôi https://accounts.google.com/o/oauth2/auththay vì 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. Hầu hết phần "tương đối" bị bỏ qua, mặc dù redirectUrl và clientId được đọc và lưu chính xác - nhưng không có dấu vết của chúng trong Url. Điều này đã được khắc phục với việc thêm -keep class com.google.api.client.googleapis.auth.oauth2.*vào của tôi proguard-rules.pro. Điều này đã có vẻ giống nhiều cách giải quyết hơn là giải pháp thực sự, nhưng mọi thứ trở nên tồi tệ hơn sau đó.
  • sau khi sửa chữa đó, khi tôi làm
    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();

với một sự kiện hoàn toàn tốt hoạt động tốt mà không cần rút gọn, thì tôi nhận được

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

Điều này có thể được cố định với -keep class com.google.api.services.calendar.* { *; }trong tôiproguard-rules.pro

  • sau khi sửa chữa đó, cùng một nỗ lực để chèn sự kiện mang lại cho tôi
    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)

Sau một số thử nghiệm, tôi nhận thấy rằng tất cả những điều trên chỉ xuất hiện khi minifyEnabled là đúng. Với minifyEnabled false, tất cả hoạt động như một sự quyến rũ. Cho đến nay tôi đã tìm thấy 3 giải pháp

  • minifyEnabled false. Tôi thích các tệp của mình được thu nhỏ khi phát hành
  • dontobfuscatedontshrinktrong proguard-rules.pro. Giúp, nhưng làm giảm tác dụng của việc thu nhỏ.
  • keep class * { *; }trong proguard-rules.pro. Giúp, nhưng làm giảm tác dụng của việc thu nhỏ.

Tôi không thể tin rằng một tùy chọn tiêu chuẩn như minifyEnabled sẽ phá vỡ một cái gì đó giống như GoogleAuthorizationthông qua các công cụ tiêu chuẩn com.google.api.client.*ở quy mô lớn như vậy. Tuy nhiên, tôi có thể tin rằng tôi đã phạm một số sai lầm ngu ngốc và rõ ràng. Rơm cuối cùng của tôi, bây giờ, là cách "Đã cài đặt" từ "Ứng dụng máy chủ web", nhưng tôi không đặt hy vọng chính xác ở đây - nếu nó là nguồn gốc chính của sự cố, tại sao nó sẽ hoạt động mà không được rút gọn ...

Tại sao hành vi được mô tả có thể xảy ra? Tôi đang làm gì sai?

Trả lời

IvanGarza Dec 16 2020 at 00:22

Việc thêm các ngoại lệ quy tắc vào proguard-rules.protệp của bạn bất cứ khi nào bạn thấy có vấn đề với sự xáo trộn trong bản phát hành của mình không phải là một phương pháp phổ biến .

Tự mình làm việc với ProGuard là một chủ đề, nhưng đừng nghĩ rằng việc thêm các ngoại lệ vào công cụ làm xáo trộn ứng dụng của bạn đang làm suy yếu tính bảo mật của ứng dụng của bạn. Một số API và các mẫu mã chỉ cần một vài ngoại lệ để hoạt động bình thường; ví dụ: các lớp / mô hình dữ liệu và mọi thứ đến từ lớp JNI luôn yêu cầu phải được giải mã.

Đây là một bài viết nhanh về chủ đề này nếu bạn vẫn chưa bị thuyết phục.