Android Kotlin集成Supabase Storage上传时缺失Authorization头报错
问题重现
在Android Studio中使用Kotlin开发,集成io.github.jan-tennert.supabase依赖,调用storage-kt:1.0.0库的BucketApi.upload()方法时触发如下错误:
FATAL EXCEPTION: main Process: com.coding.informer.dictionary_app_v3, PID: 23547 io.github.jan.supabase.exceptions.BadRequestRestException: Error (headers must have required property 'authorization') URL: https://juessugxmpdtjuexmdwj.supabase.co/storage/v1/object/bookmarked_words/ Headers: [x-upsert=[false], apikey=[<Removed for security reasons>], Accept=[application/json], Accept-Charset=[UTF-8]] Http Method: POST at io.github.jan.supabase.storage.StorageImpl.parseErrorResponse(Storage.kt:271) at io.github.jan.supabase.gotrue.AuthenticatedSupabaseApiKt$authenticatedSupabaseApi$3.invoke(AuthenticatedSupabaseApi.kt:62) ...(栈跟踪省略)
排查确认:请求中缺失Authorization=Bearer ...头,这是报错的核心原因。
当前SupabaseClient初始化代码:
val client = createSupabaseClient( supabaseUrl = BuildConfig.supabase_project_url, supabaseKey = BuildConfig.supabase_project_api_key, ) { install(Storage) { } }
client.storage.get(bucketId = "bookmarked-words")可正常执行,但调用上传方法时出错:
bookmarked_works_bucket.upload("words", "sampleWord".toByteArray())
原因分析
Supabase Storage的上传接口要求携带用户认证凭证,当前初始化的SupabaseClient仅配置了apikey,未启用认证模块或设置有效用户会话,导致上传请求无法自动生成并携带Authorization头。
解决方案
根据业务场景选择以下两种方式之一:
方式1:启用GoTrue模块并登录匿名用户(适用于允许匿名上传的Bucket)
在初始化SupabaseClient时安装GoTrue认证模块,并提前登录匿名用户:
val client = createSupabaseClient( supabaseUrl = BuildConfig.supabase_project_url, supabaseKey = BuildConfig.supabase_project_api_key ) { install(GoTrue) install(Storage) } // 在上传操作前执行匿名登录(建议放在IO线程协程中) CoroutineScope(Dispatchers.IO).launch { client.gotrue.signInAnonymously() }
完成匿名登录后,调用upload()方法时请求会自动携带Authorization头。
方式2:手动添加Authorization头(适用于服务端密钥场景)
如果使用Supabase的服务端密钥(service_role key),可在Storage配置中手动注入请求头:
val client = createSupabaseClient( supabaseUrl = BuildConfig.supabase_project_url, supabaseKey = BuildConfig.supabase_service_role_key // 替换为服务端密钥 ) { install(Storage) { defaultHeaders["Authorization"] = "Bearer ${BuildConfig.supabase_service_role_key}" } }
⚠️ 注意:服务端密钥拥有Supabase全权限,禁止在客户端代码中硬编码,建议通过自有后端接口转发上传请求,避免密钥泄露。
额外注意事项
- 确认Bucket权限设置:私有Bucket必须登录用户才能上传;公开Bucket需确保匿名用户拥有上传权限。
- 上传操作必须在协程中执行(避免阻塞主线程):
CoroutineScope(Dispatchers.IO).launch { try { bookmarked_works_bucket.upload("words", "sampleWord".toByteArray()) // 上传成功逻辑 } catch (e: Exception) { // 异常处理逻辑 } }
内容的提问来源于stack exchange,提问作者flyingfishcattle
相关产品推荐
相关产品推荐

