Настройка HTTPS в Android Studio: GET, авторизация и безопасность
Короткий ответ: используйте Network Security Config для ограничения cleartext и локального pinning, делайте HTTPS-запросы через Retrofit + OkHttp, добавляйте Bearer в Interceptor, а для продакшена — SSL pinning и отключённые debug‑хакі. Ниже — конкретные шаги и минимальные фрагменты кода, чтобы это сразу заработало.
Network Security Config и манифест
Создайте res/xml/network_security_config.xml, чтобы явно разрешать только HTTPS для вашего API и при необходимости подключать локальные сертификаты:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">yourapi.com</domain>
<trust-anchors>
<certificates src="@raw/your_cert"/>
</trust-anchors>
</domain-config>
</network-security-config>
В AndroidManifest.xml:
<application
android:networkSecurityConfig="@xml/network_security_config"
android:usesCleartextTraffic="false"
...>
Для локальной разработки временно в debug-манифесте можно установить android:usesCleartextTraffic="true" и упрощённый hostnameVerifier, но никогда не оставляйте это в релизе.
GET-запросы с Retrofit и авторизация (Bearer Token)
Добавьте зависимости Retrofit/OkHttp (пример версии в вашем build.gradle). Настройте OkHttpClient с Interceptor для авторизации и логирования:
class AuthInterceptor(private var tokenProvider: () -> String?) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val token = tokenProvider()
val req = chain.request().newBuilder()
.apply { token?.let { addHeader("Authorization", "Bearer $it") } }
.addHeader("Content-Type", "application/json")
.build()
return chain.proceed(req)
}
}
Инициализация Retrofit:
val client = OkHttpClient.Builder()
.addInterceptor(AuthInterceptor { tokenStorage.currentToken })
.addInterceptor(HttpLoggingInterceptor().apply { level = BODY }) // debug only
.protocols(listOf(Protocol.HTTP_2, Protocol.HTTP_1_1))
.build()
val retrofit = Retrofit.Builder()
.baseUrl("https://yourapi.com/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
Интерфейс API:
interface ApiService {
@GET("users/{id}")
suspend fun getUser(@Path("id") id: String): Response<User>
}
Используйте suspend-функции и вызывной scope (lifecycleScope или viewModelScope) — это проще и безопаснее, чем callbacks.
SSL pinning, отладка и продакшен‑практики
Для сильной защиты используйте CertificatePinner (OkHttp) или pin в network_security_config:
Пример CertificatePinner:
val pinner = CertificatePinner.Builder()
.add("yourapi.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.build()
val client = OkHttpClient.Builder()
.certificatePinner(pinner)
.build()
Добавьте сертификат в res/raw/my_cert.crt, если используете network_security_config.
Отладка:
- Для перехвата трафика (Charles, HTTP Toolkit) установите CA в эмулятор/устройство через Settings → Security → Install from storage (только для тестов).
- Логи: фильтруйте Logcat по тегу OkHttp и включайте HttpLoggingInterceptor только в debug.
Продакшен:
- Никогда не используйте hostnameVerifier { _, _ -> true }.
- Ротация ключей: планируйте обновление pin каждые 6 месяцев (дублированные pin для перехода).
- Сервер должен отдавать HSTS и поддерживать современных TLS‑cipherы.
Android 16 требует Certificate Transparency — подготовьтесь добавить ct-verifier в стек HTTPS уже сейчас.
Частые ошибки
- SSLHandshakeException: неверный cert, отсутствует intermediate, или клиент не доверяет CA.
- NetworkSecurityConfig игнорируется: проверьте корректность пути и android:networkSecurityConfig в манифесте.
- Bearer не передаётся: Interceptor не добавлен или tokenProvider возвращает null.
- Проблемы с эмулятором и CA: реальное устройство ведёт себя иначе — тестируйте на нём.
FAQ
- Нужно ли HTTPS для публикации в Play Store? Да — Android 9+ по умолчанию блокирует cleartext и Google требует защищённого трафика.
- Как временно разрешить HTTP для тестов? В debug‑варианте манифеста: android:usesCleartextTraffic="true" или настройка domain-config с cleartextTrafficPermitted="true" только для dev-домена.
- Что выбрать: pinning в network_security_config или CertificatePinner? Network config проще для статичных cert в ресурсах; CertificatePinner удобнее для гибкого управления в коде и динамических обновлений.
Если нужно — могу прислать готовый модуль Application + Retrofit + примеры хранения токена для быстрого старта.