Flutter中如何正确向Amplify S3传递参数实现文件上传
实现方案
你拿到的是后端返回的临时AWS访问凭证,无法直接传递给uploadFile接口使用,需要先完成Amplify的自定义凭证配置,再拼接正确的上传参数:
1. 先配置自定义凭证提供者
Amplify默认自动管理凭证,如果你要用后端返回的自定义凭证,需要先实现自定义的凭证提供类,将后端返回的鉴权信息注入到Amplify中:
import 'package:amplify_auth_cognito/amplify_auth_cognito.dart'; import 'package:amplify_core/amplify_core.dart'; // 自定义凭证提供者 class CustomAwsCredentialsProvider extends AWSCredentialsProvider { AWSCredentials? _customCredentials; void updateCredentials(AWSCredentials credentials) { _customCredentials = credentials; } @override Future<AWSCredentials> retrieve() async { if (_customCredentials == null) { throw Exception("未加载AWS凭证"); } return _customCredentials!; } } // 初始化Amplify时使用自定义凭证 final customCredentialsProvider = CustomAwsCredentialsProvider(); Future<void> initAmplify() async { final storage = AmplifyStorageS3( credentialsProvider: customCredentialsProvider, ); await Amplify.addPlugin(storage); // 补充剩余的Amplify初始化配置 await Amplify.configure(/* 你的amplify配置内容 */); }
2. 拿到后端返回的凭证后更新到提供者
你拿到接口返回的JSON数据后,先把凭证信息更新到自定义的凭证提供者中:
// 假设你已经把接口返回的data字段解析为_mediaResponse对象 customCredentialsProvider.updateCredentials( AWSCredentials( _mediaResponse!.accessKeyId, _mediaResponse!.secretAccessKey, // 如果接口返回了sessionToken请在这里补全,没有就传null null, _mediaResponse!.expiresAt, ), );
3. 修正上传代码,传入正确参数
你原来的代码错误把accessKeyId作为了文件存储路径key,实际key需要拼接directoryPath和自定义文件名,同时可以主动指定bucket参数:
Future<String?> uploadFile(File file) async { try { // 拼接文件存储路径,建议用唯一文件名避免覆盖,示例用时间戳+原文件名 final fileName = '${DateTime.now().millisecondsSinceEpoch}_${file.path.split('/').last}'; final storageKey = '${_mediaResponse!.directoryPath}$fileName'; final result = await Amplify.Storage.uploadFile( local: file, key: storageKey, // 如需指定非默认桶,传入bucket参数 bucket: _mediaResponse!.bucket, ); // 上传成功后返回文件的存储key或者可访问路径 return result.key; } catch (e) { setErrorMessage(e.toString()); return null; } }
注意事项
- 临时凭证过期前需要重新调用后端接口获取新的凭证,调用
updateCredentials方法更新即可 - 如果你的Amplify默认配置的存储桶和接口返回的bucket一致,可以省略bucket参数
- 文件名建议做去重处理,避免相同文件名的文件互相覆盖
内容的提问来源于stack exchange,提问作者Febin Johnson
相关产品推荐
相关产品推荐

