最近小编所在公司,项目要迁移到海外,很多之前国内使用的云服务(阿里云,百度云,腾讯云) 要更好成amazon。
aws的文档真的是一言难尽,所以小编整理了一些 aws 使用场景,方便大家参考和cv。
资源授权以S3为例
前端需要将图片上传的S3存储桶中,肯定不能直接给前端一对accessKey 和 secretKey 。
所以后端需要提供一个 有过期时间的S3存储桶的token,前端拿到这个token 作为上传凭证。
</dependencyManagement>
</dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>2.16.60</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>sts</artifactId>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
</dependency>
</dependencies>
/**
* @Author
* @Date: 2022/05/13/ 14:58
* @Description
*/
@Data
@Service
@Configuration
public class AwsConfig {
@Value("${aws.accessKey:}")
private String accessKey;
@Value("${aws.secretKey:}")
private String secretKey;
@Value("${aws.s3.env:}")
private String env;
@Value("${aws.s3.localRecord.region:}")
private String localRecordRegion;
@Value("${aws.s3.localRecord.bucket:}")
private String localRecordBucket;
@Value("${aws.s3.localRecord.durationSeconds:}")
private Integer localRecordDurationSeconds;
@Value("${aws.s3.localRecord.tempUserName:localRecordTemp}")
private String localRecordTempUserName;
@Value("${aws.s3.localRecord.host:}")
private String localRecordHost;
@Value("#{'${aws.sts.localRecord.action:}'.split(',')}")
private List<String> localRecordStsAction;
@Bean
public StsClient stsClient() {
AwsBasicCredentials awsCreds = AwsBasicCredentials.create(this.accessKey, this.secretKey);
return StsClient.builder().credentialsProvider(StaticCredentialsProvider.create(awsCreds))
.region(Region.of(this.localRecordRegion)).build();
}
}
@Slf4j
@Controller
@RequestMapping("/data")
public class FileController extends DataBaseController {
@Resource
private StsClient stsClient;
@Autowired
private AwsConfig awsConfig;
@Autowired
private RedisService redisService;
@GetMapping("/local_record/s3_token")
@ResponseBody
public ResponseEntity<Response<LocalRecordUploadTokenVo>> getS3UploadToken(HttpServletRequest request) {
Response<LocalRecordUploadTokenVo> response = new Response<>();
HttpHeaders headers = new HttpHeaders();
headers.setAccessControlAllowOrigin("*");
LocalRecordUploadTokenVo uploadTokenCacheVo =
redisService.get(RedisConstant.LOCAL_RECORD_S3_TOKEN, LocalRecordUploadTokenVo.class);
if (uploadTokenCacheVo != null
&& uploadTokenCacheVo.getExpiredTime() > System.currentTimeMillis() / 1000 + 1200) {
response.success().data(uploadTokenCacheVo);
return new ResponseEntity<>(response, headers, HttpStatus.OK);
}
String policy = String.format(
"{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":%s,\"Resource\":\"arn:aws:s3:::%s/%s/*\"}]}",
awsConfig.getLocalRecordStsAction(), awsConfig.getLocalRecordBucket(), awsConfig.getEnv());
GetFederationTokenRequest build =
GetFederationTokenRequest.builder().name(awsConfig.getLocalRecordTempUserName()).policy(policy)
.durationSeconds(awsConfig.getLocalRecordDurationSeconds()).build();
LocalRecordUploadTokenVo tokenVo;
try {
GetFederationTokenResponse federationToken = stsClient.getFederationToken(build);
Credentials credentials = federationToken.credentials();
tokenVo = new LocalRecordUploadTokenVo(federationToken.responseMetadata().requestId(), credentials);
tokenVo.setBucket(awsConfig.getLocalRecordBucket());
tokenVo.setRegion(awsConfig.getLocalRecordRegion());
response.success().data(tokenVo);
redisService.set(RedisConstant.LOCAL_RECORD_S3_TOKEN, tokenVo, 600L);
} catch (Exception e) {
log.error("FileController::getS3UploadToken 获取上传签名失败", e);
response.success().message(e.getMessage());
}
return new ResponseEntity<>(response, headers, HttpStatus.OK);
}
}
这里加了redis缓存
awsConfig.getLocalRecordStsAction() 的值为"s3:GetObject","s3:PutObject","s3:PutObjectAcl"
awsConfig.getEnv() 为环境类型 如qa online
代码仅供参考