天天看點

STS臨時授權通路OSS後端代碼前端代碼上傳測試遇到的問題

STS臨時授權通路OSS需要配合RAM子賬号一起使用

具體使用流程參考:STS臨時授權通路OSS

這裡我列出我的代碼,以備以後複制使用。

文章目錄

  • 後端代碼
    • 依賴
    • Controller
  • 前端代碼
  • 上傳測試
  • 遇到的問題

後端代碼

依賴

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>3.2.2</version>
</dependency>

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-sts</artifactId>
    <version>3.0.0</version>
</dependency>
           

Controller

package com.jdcloud.provider.web.sts;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.jdcloud.provider.model.vo.OssTokenVO;
import com.jdcloud.util.wrapper.WrapMapper;
import com.jdcloud.util.wrapper.Wrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;

/**
 * 阿裡雲OSS STS
 *
 * @author leigq
 */
@Slf4j
@RestController
@RequestMapping("/aliyun/sts")
public class AliyunStsController {

    /**
     * 擷取 OSS 簽名授權
     *
     * @return
     * @author leigq
     * @date 2018-12-17 15:08:55
     **/
    @GetMapping("/oss/tokens")
    public Wrapper getOssToken() {
        // 建立阿裡雲 OSS 臨時token
        AssumeRoleResponse ossToken = createOssToken();
        if (Objects.isNull(ossToken)) {
            return WrapMapper.error("擷取 OSS 簽名授權失敗!");
        }
        // 阿裡 OSS 配置
        AssumeRoleResponse.Credentials credentials = ossToken.getCredentials();
        // 建構 OSS token 傳回給前端
        OssTokenVO ossTokenVO = OssTokenVO.builder()
                // region每個地方不一樣,下面是深圳的:shenzhen
                .region("oss-cn-shenzhen")
                .accessKeyId(credentials.getAccessKeyId())
                .accessKeySecret(credentials.getAccessKeySecret())
                .securityToken(credentials.getSecurityToken())
                .expiration(credentials.getExpiration())
                // OSS bucket名稱
                .bucket("leigq-bucket")
                .build();
        return WrapMapper.ok(ossTokenVO);
    }

    /**
     * 建立阿裡雲 OSS 臨時token
     * @author leigq
     * @return
     */
    private AssumeRoleResponse createOssToken() {
        /*
         * 子賬号的 accessKeyId、accessKeySecret、roleArn,注意:子賬号需賦予 AliyunSTSAssumeRoleAccess(調用STS服務AssumeRole接口的權限)權限
         * */
        String accessKeyId = "LTAIEYh****o1Ukv";
        String accessKeySecret = "7JjHqPaGKGfXH****KEFqB3oys8Gv4";
        String roleArn = "acs:ram::1915198****60148:role/tst-test";

        //roleSessionName時臨時Token的會話名稱,自己指定用于辨別你的使用者,或者用于區分Token頒發給誰
        //要注意roleSessionName的長度和規則,不要有空格,隻能有'-'和'_'字母和數字等字元
        String roleSessionName = "session-name";
        try {
            // 建立一個 Aliyun Acs Client, 用于發起 OpenAPI 請求
            DefaultProfile.addEndpoint("", "", "Sts", "sts.aliyuncs.com");
            IClientProfile profile = DefaultProfile.getProfile("", accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
            // 建立一個 AssumeRoleRequest 并設定請求參數
            final AssumeRoleRequest request = new AssumeRoleRequest();
            //POST請求
            request.setMethod(MethodType.POST);
            //https協定
            request.setProtocol(ProtocolType.HTTPS);
            //持續時間, 隻能設定 15min - 1hr 之間
            request.setDurationSeconds(900L);
            //角色id
            request.setRoleArn(roleArn);
            //應用程式辨別(自己定義)
            request.setRoleSessionName(roleSessionName);
            // 發起請求,并得到response
            AssumeRoleResponse acsResponse = client.getAcsResponse(request);
            return acsResponse;
        } catch (ClientException e) {
            log.error("建立阿裡雲 OSS 臨時token異常", e);
        }
        return null;
    }
}
           

上面用到的

OssTokenVO

實體:

package com.jdcloud.provider.model.vo;

import lombok.Builder;
import lombok.Data;

/**
 * 阿裡OSS Token VO
 *
 * @author leigq
 */
@Data
@Builder
public class OssTokenVO {

    private String region;

    private String accessKeyId;

    private String accessKeySecret;

    private String securityToken;

    private String bucket;

    private String expiration;

}
           

用浏覽器請求此接口,結果如下:

STS臨時授權通路OSS後端代碼前端代碼上傳測試遇到的問題

tips:每次請求資料都會發生變化。

前端代碼

前端先請求上面的接口,擷取到region、accessKeyId、accessKeySecret、stsToken,就可以上傳圖檔了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <input type="file" name="picFieldName" id="picFieldId" onchange="uploadPic(this)" />
    <!-- 引入線上資源 -->
    <script src="http://gosspublic.alicdn.com/aliyun-oss-sdk-5.3.0.min.js"></script>
    <script>
        var client = new OSS.Wrapper({
            region: 'oss-cn-shenzhen',
            accessKeyId: 'STS.NKR9sKxWY****bVpecXJq2Ujc',
            accessKeySecret: 'H2hC2kT7tyEt5B5****HHV7MJdovTweDx1ugoK5BYZXc',
            stsToken: 'CAIS8gF1q6Ft5B2yfSjIr4jncsn/lYh47oqdW0TnlGU2VMVd3ZDBgTz2IHpOfnNsCeAWsvUxnm1V5vsflqVoRoReREvCKM1565kPX7o+nVqE6aKP9rUhpMCPOwr6UmzWvqL7Z+H+U6muGJOEYEzFkSle2KbzcS7YMXWuLZyOj+wMDL1VJH7aCwBLH9BLPABvhdYHPH/KT5aXPwXtn3DbATgD2GM+qxsmtvvnm5bCsUKF1QGhkbREnemrfMj4NfsLFYxkTtK40NZx****yyNK43BIjvws1vYepWeX7o3MXQMMvkXbbvC79cZ0aRRlfbj54HDgGy0G/hqAARZcV0zbN+Tm9xpy6qrS7Bw/tw1Sn/zG+/hImKRSTdxz7GjLc/CvnefWQQ47bu1cK9Z38pm8kfo+etFY06j89hz+yNiDd+xjEPkgm3rIA/lvAn4oHSN0z0PGjFzxDTCcupEDd7/MJcReo7aQFuRVbO0We/jGobAqNNXGSY5/l9QD',
            bucket: 'bitrade-sz-oss'
        });
        function uploadPic(obj) {
            // 擷取檔案流
            var file = obj.files[0];
            // 路徑
            var storeAs = "studio_course/" + file.name;
            console.log(file.name + ' => ' + storeAs);
            client.put(storeAs, file).then(function (result) {
                console.log(result);
            }).catch(function (err) {
                console.log(err);
            });
        }
    </script>
</body>
</html>
           

上傳測試

STS臨時授權通路OSS後端代碼前端代碼上傳測試遇到的問題
STS臨時授權通路OSS後端代碼前端代碼上傳測試遇到的問題

正常上傳!

遇到的問題

  • OSS阿裡雲上傳檔案 前端 js 下載下傳 url 跨域問題