Tải lên tệp trực tiếp Amazon S3 từ trình duyệt của khách hàng - tiết lộ khóa riêng


159

Tôi đang triển khai tải tệp trực tiếp từ máy khách lên Amazon S3 thông qua API REST chỉ sử dụng JavaScript mà không cần bất kỳ mã phía máy chủ nào. Tất cả đều hoạt động tốt nhưng có một điều khiến tôi lo lắng ...

Khi tôi gửi yêu cầu tới Amazon S3 REST API, tôi cần phải ký yêu cầu và đặt chữ ký vào Authenticationtiêu đề. Để tạo chữ ký, tôi phải sử dụng khóa bí mật của mình. Nhưng tất cả mọi thứ xảy ra ở phía khách hàng, vì vậy, khóa bí mật có thể dễ dàng được tiết lộ từ nguồn trang (ngay cả khi tôi che giấu / mã hóa nguồn của mình).

Làm thế nào tôi có thể xử lý này? Và nó có phải là một vấn đề không? Có lẽ tôi chỉ có thể giới hạn việc sử dụng khóa riêng cụ thể đối với các lệnh gọi API REST từ Nguồn gốc CORS cụ thể và chỉ các phương thức PUT và POST hoặc có thể liên kết khóa với chỉ S3 và nhóm cụ thể? Có thể có một phương pháp xác thực khác?

Giải pháp "Serverless" là lý tưởng, nhưng tôi có thể xem xét liên quan đến việc xử lý một số máy chủ, ngoại trừ tải tệp lên máy chủ của tôi và sau đó gửi đến S3.


7
Rất đơn giản: không lưu trữ bất kỳ bí mật phía khách hàng. Bạn sẽ cần liên quan đến một máy chủ để ký yêu cầu.
Ray Nicholus

1
Bạn cũng sẽ thấy rằng việc ký và mã hóa cơ sở 64 các yêu cầu này dễ dàng hơn nhiều so với phía máy chủ. Có vẻ như không hợp lý khi liên quan đến một máy chủ ở đây. Tôi có thể hiểu rằng không muốn gửi tất cả các byte tệp đến máy chủ và sau đó lên S3, nhưng có rất ít lợi ích khi ký các yêu cầu phía máy khách, đặc biệt là vì điều đó sẽ hơi khó khăn và có khả năng làm chậm phía máy khách (trong javascript).
Ray Nicholus

5
Đó là năm 2016, khi kiến ​​trúc không có máy chủ trở nên khá phổ biến, có thể tải tệp trực tiếp lên S3 với sự trợ giúp của AWS Lambda. Xem câu trả lời của tôi cho một câu hỏi tương tự: stackoverflow.com/a/40828683/2504317 Về cơ bản, bạn có chức năng Lambda dưới dạng URL có thể tải lên ký API cho mỗi tệp và javascript phía bạn bè của bạn chỉ cần thực hiện PUT HTTP cho URL được ký trước. Tôi đã viết một thành phần Vue làm những việc như vậy, mã liên quan đến tải lên S3 là bất khả tri của thư viện, hãy xem và lấy ý tưởng.
KF Lin

Một bên thứ 3 khác để tải lên HTTP / S POST trong bất kỳ nhóm S3 nào. JS3Upload thuần HTML5: jfileupload.com/products/js3upload-html5/index.html
JFU

Câu trả lời:


215

Tôi nghĩ những gì bạn muốn là Tải lên dựa trên trình duyệt bằng POST.

Về cơ bản, bạn không cần mã phía máy chủ, nhưng tất cả những gì nó làm là tạo ra các chính sách đã ký. Khi mã phía máy khách có chính sách đã ký, nó có thể tải lên bằng cách sử dụng POST trực tiếp lên S3 mà không cần dữ liệu đi qua máy chủ của bạn.

Đây là liên kết tài liệu chính thức:

Sơ đồ: http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingHTTPPOST.html

Mã ví dụ: http://docs.aws.amazon.com/AmazonS3/latest/dev/HTTPPOSTExamples.html

Chính sách đã ký sẽ đi vào html của bạn dưới dạng như sau:

<html>
  <head>
    ...
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    ...
  </head>
  <body>
  ...
  <form action="http://johnsmith.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
    Key to upload: <input type="input" name="key" value="user/eric/" /><br />
    <input type="hidden" name="acl" value="public-read" />
    <input type="hidden" name="success_action_redirect" value="http://johnsmith.s3.amazonaws.com/successful_upload.html" />
    Content-Type: <input type="input" name="Content-Type" value="image/jpeg" /><br />
    <input type="hidden" name="x-amz-meta-uuid" value="14365123651274" />
    Tags for File: <input type="input" name="x-amz-meta-tag" value="" /><br />
    <input type="hidden" name="AWSAccessKeyId" value="AKIAIOSFODNN7EXAMPLE" />
    <input type="hidden" name="Policy" value="POLICY" />
    <input type="hidden" name="Signature" value="SIGNATURE" />
    File: <input type="file" name="file" /> <br />
    <!-- The elements after this will be ignored -->
    <input type="submit" name="submit" value="Upload to Amazon S3" />
  </form>
  ...
</html>

Lưu ý hành động FORM đang gửi tệp trực tiếp đến S3 - không qua máy chủ của bạn.

Mỗi khi một trong những người dùng của bạn muốn tải lên một tệp, bạn sẽ tạo POLICYSIGNATUREtrên máy chủ của mình. Bạn trả lại trang cho trình duyệt của người dùng. Sau đó, người dùng có thể tải tệp trực tiếp lên S3 mà không cần thông qua máy chủ của bạn.

Khi bạn ký chính sách, bạn thường làm cho chính sách hết hạn sau vài phút. Điều này buộc người dùng của bạn nói chuyện với máy chủ của bạn trước khi tải lên. Điều này cho phép bạn theo dõi và giới hạn tải lên nếu bạn muốn.

Dữ liệu duy nhất đi đến hoặc từ máy chủ của bạn là các URL đã ký. Khóa bí mật của bạn được giữ bí mật trên máy chủ.


14
xin lưu ý rằng điều này sử dụng Chữ ký v2 sẽ sớm được thay thế bằng v4: docs.aws.amazon.com/AmazonS3/latest/API/ trộm
Jörn Berkefeld

9
Hãy chắc chắn để thêm ${filename}vào tên khóa, vì vậy, ví dụ trên, user/eric/${filename}thay vì chỉ user/eric. Nếu user/ericlà một thư mục đã có sẵn, việc tải lên sẽ âm thầm thất bại (thậm chí bạn sẽ được chuyển hướng đến thành công_action_redirect) và nội dung được tải lên sẽ không ở đó. Chỉ cần dành hàng giờ để gỡ lỗi suy nghĩ này, đó là một vấn đề cho phép.
Balint Erdi

@secretmike Nếu bạn đã hết thời gian thực hiện phương pháp này, làm thế nào bạn có thể khuyên bạn nên đi vòng quanh đó?
Chuyến đi

1
@Trip Vì trình duyệt đang gửi tệp tới S3, bạn sẽ cần phát hiện thời gian chờ trong Javascript và tự mình thử lại.
bí mật

@secretmike Điều đó có mùi giống như một chu kỳ vòng lặp vô hạn. Vì thời gian chờ sẽ tái diễn vô thời hạn cho bất kỳ tệp nào trên 10 / mbs.
Chuyến đi

40

Bạn có thể làm điều này bằng AWS S3 Cognito thử liên kết này tại đây:

http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/browser-examples.html#Amazon_S3

Cũng thử mã này

Chỉ cần thay đổi Vùng, Danh tínhPoolId và tên nhóm của bạn

<!DOCTYPE html>
<html>

<head>
    <title>AWS S3 File Upload</title>
    <script src="https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js"></script>
</head>

<body>
    <input type="file" id="file-chooser" />
    <button id="upload-button">Upload to S3</button>
    <div id="results"></div>
    <script type="text/javascript">
    AWS.config.region = 'your-region'; // 1. Enter your region

    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: 'your-IdentityPoolId' // 2. Enter your identity pool
    });

    AWS.config.credentials.get(function(err) {
        if (err) alert(err);
        console.log(AWS.config.credentials);
    });

    var bucketName = 'your-bucket'; // Enter your bucket name
    var bucket = new AWS.S3({
        params: {
            Bucket: bucketName
        }
    });

    var fileChooser = document.getElementById('file-chooser');
    var button = document.getElementById('upload-button');
    var results = document.getElementById('results');
    button.addEventListener('click', function() {

        var file = fileChooser.files[0];

        if (file) {

            results.innerHTML = '';
            var objKey = 'testing/' + file.name;
            var params = {
                Key: objKey,
                ContentType: file.type,
                Body: file,
                ACL: 'public-read'
            };

            bucket.putObject(params, function(err, data) {
                if (err) {
                    results.innerHTML = 'ERROR: ' + err;
                } else {
                    listObjs();
                }
            });
        } else {
            results.innerHTML = 'Nothing to upload.';
        }
    }, false);
    function listObjs() {
        var prefix = 'testing';
        bucket.listObjects({
            Prefix: prefix
        }, function(err, data) {
            if (err) {
                results.innerHTML = 'ERROR: ' + err;
            } else {
                var objKeys = "";
                data.Contents.forEach(function(obj) {
                    objKeys += obj.Key + "<br>";
                });
                results.innerHTML = objKeys;
            }
        });
    }
    </script>
</body>

</html>

Để biết thêm chi tiết, vui lòng kiểm tra - Github

Điều này có hỗ trợ nhiều hình ảnh không?
dùng2722667

@ user2722667 đúng vậy.
Joomler

@Joomler Xin chào Cảm ơn nhưng tôi đang gặp phải vấn đề này trên firefox RequestTimeout Kết nối ổ cắm của bạn với máy chủ không được đọc hoặc ghi trong khoảng thời gian chờ. Các kết nối nhàn rỗi sẽ bị đóng và tệp không tải lên trên S3. Bạn có thể giúp tôi về cách tôi có thể khắc phục vấn đề này. Xin cảm ơn
usama

1
@usama bạn có thể vui lòng mở vấn đề trong github vì vấn đề không rõ ràng với tôi
Joomler 18/07/17

@Joomler xin lỗi vì trả lời trễ ở đây tôi đã mở một vấn đề tại GitHub xin hãy xem Cảm ơn này. github.com/aws/aws-sdk-php/issues/1332
usama

16

Bạn đang nói rằng bạn muốn một giải pháp "không có máy chủ". Nhưng điều đó có nghĩa là bạn không có khả năng đưa bất kỳ mã "của bạn" nào vào vòng lặp. (LƯU Ý: Khi bạn đưa mã của mình cho khách hàng, bây giờ đó là "mã" của họ.) Khóa CORS sẽ không giúp ích gì tiêu đề CORS chính xác để lạm dụng hệ thống của bạn.

Vấn đề lớn là bạn không thể phân biệt giữa những người dùng khác nhau. Bạn không thể cho phép một người dùng liệt kê / truy cập các tệp của anh ấy, nhưng ngăn người khác làm như vậy. Nếu bạn phát hiện hành vi lạm dụng, bạn không thể làm gì khác ngoài việc thay đổi khóa. (Mà kẻ tấn công có lẽ chỉ cần lấy lại.)

Đặt cược tốt nhất của bạn là tạo một "người dùng IAM" bằng một khóa cho ứng dụng khách javascript của bạn. Chỉ cung cấp cho nó quyền truy cập vào chỉ một thùng. (nhưng lý tưởng nhất là không kích hoạt hoạt động ListBucket, điều đó sẽ khiến nó hấp dẫn hơn đối với những kẻ tấn công.)

Nếu bạn có một máy chủ (thậm chí là một ví dụ vi mô đơn giản ở mức 20 đô la / tháng), bạn có thể ký các khóa trên máy chủ của mình trong khi theo dõi / ngăn chặn lạm dụng trong thời gian thực. Không có máy chủ, điều tốt nhất bạn có thể làm là định kỳ theo dõi tình trạng lạm dụng sau thực tế. Đây là những gì tôi sẽ làm:

1) định kỳ xoay các khóa cho người dùng IAM đó: Mỗi đêm, tạo một khóa mới cho người dùng IAM đó và thay thế khóa cũ nhất. Vì có 2 khóa, mỗi khóa sẽ có hiệu lực trong 2 ngày.

2) cho phép ghi nhật ký S3 và tải xuống nhật ký mỗi giờ. Đặt thông báo về "quá nhiều lượt tải lên" và "quá nhiều lượt tải xuống". Bạn sẽ muốn kiểm tra cả kích thước tập tin và số lượng tập tin được tải lên. Và bạn sẽ muốn theo dõi cả tổng số toàn cầu và cả tổng số địa chỉ trên mỗi IP (với ngưỡng thấp hơn).

Các kiểm tra này có thể được thực hiện "serverless" vì bạn có thể chạy chúng trên máy tính để bàn của mình. (tức là S3 thực hiện tất cả công việc, các quy trình này chỉ để cảnh báo bạn lạm dụng nhóm S3 của bạn để bạn không nhận được hóa đơn AWS khổng lồ vào cuối tháng.)


3
Man, tôi quên mất những điều phức tạp trước Lambda.
Ryan Shillington

10

Thêm thông tin vào câu trả lời được chấp nhận, bạn có thể tham khảo blog của tôi để xem phiên bản mã đang chạy, sử dụng AWS Chữ ký phiên bản 4.

Sẽ tóm tắt tại đây:

Ngay sau khi người dùng chọn một tệp sẽ được tải lên, hãy thực hiện theo các bước sau: 1. Thực hiện cuộc gọi đến máy chủ web để bắt đầu dịch vụ để tạo thông số bắt buộc

  1. Trong dịch vụ này, hãy gọi cho dịch vụ AWS IAM để nhận tín dụng tạm thời

  2. Khi bạn có uy tín, hãy tạo chính sách nhóm (chuỗi được mã hóa cơ sở 64). Sau đó ký chính sách xô với khóa truy cập bí mật tạm thời để tạo chữ ký cuối cùng

  3. gửi các tham số cần thiết trở lại giao diện người dùng

  4. Khi nhận được điều này, hãy tạo một đối tượng biểu mẫu html, đặt tham số bắt buộc và POST nó.

Để biết thông tin chi tiết, vui lòng tham khảo https://wordpress1763.wordpress.com/2016/10/03/browser-basing-upload-aws-signature-version-4/


5
Tôi đã dành cả ngày để cố gắng tìm ra điều này trong Javascript và câu trả lời này cho tôi biết chính xác cách thực hiện điều này bằng cách sử dụng XMLhttprequest. Tôi rất ngạc nhiên khi bạn bị hạ bệ. OP đã yêu cầu javascript và có các hình thức trong các câu trả lời được đề xuất. Tốt đau buồn. Cảm ơn câu trả lời này!
Paul S

BTW superagent có các vấn đề CORS nghiêm trọng, vì vậy xmlhttprequest dường như là cách hợp lý duy nhất để thực hiện việc này ngay bây giờ
Paul S

4

Để tạo chữ ký, tôi phải sử dụng khóa bí mật của mình. Nhưng tất cả mọi thứ xảy ra ở phía khách hàng, vì vậy, khóa bí mật có thể dễ dàng được tiết lộ từ nguồn trang (ngay cả khi tôi che giấu / mã hóa nguồn của mình).

Đây là nơi bạn đã hiểu lầm. Lý do chính là chữ ký số được sử dụng là để bạn có thể xác minh một cái gì đó là chính xác mà không tiết lộ khóa bí mật của bạn. Trong trường hợp này, chữ ký số được sử dụng để ngăn người dùng sửa đổi chính sách bạn đặt cho bài đăng mẫu.

Chữ ký số như chữ ký ở đây được sử dụng để bảo mật trên toàn bộ web. Nếu ai đó (NSA?) Thực sự có thể phá vỡ chúng, họ sẽ có mục tiêu lớn hơn nhiều so với nhóm S3 của bạn :)


2
nhưng một robot có thể cố gắng tải lên các tệp không giới hạn một cách nhanh chóng. Tôi có thể đặt chính sách cho các tệp tối đa trên mỗi nhóm không?
Dejell 6/03/2016

3

Tôi đã đưa ra một mã đơn giản để tải các tệp từ trình duyệt Javascript lên AWS S3 và liệt kê tất cả các tệp trong nhóm S3.

Các bước:

  1. Để biết cách tạo Tạo danh tínhPoolId http://docs.aws.amazon.com/cognito/latest/developerguide/identity-pools.html

    1. Trang bảng điều khiển của Goto S3 và cấu hình cors mở từ các thuộc tính nhóm và viết mã XML theo đó.

      <?xml version="1.0" encoding="UTF-8"?>
      <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
       <CORSRule>    
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <AllowedMethod>HEAD</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
       </CORSRule>
      </CORSConfiguration>
      
    2. Tạo tệp HTML chứa mã sau thay đổi thông tin đăng nhập, mở tệp trong trình duyệt và tận hưởng.

      <script type="text/javascript">
       AWS.config.region = 'ap-north-1'; // Region
       AWS.config.credentials = new AWS.CognitoIdentityCredentials({
       IdentityPoolId: 'ap-north-1:*****-*****',
       });
       var bucket = new AWS.S3({
       params: {
       Bucket: 'MyBucket'
       }
       });
      
       var fileChooser = document.getElementById('file-chooser');
       var button = document.getElementById('upload-button');
       var results = document.getElementById('results');
      
       function upload() {
       var file = fileChooser.files[0];
       console.log(file.name);
      
       if (file) {
       results.innerHTML = '';
       var params = {
       Key: n + '.pdf',
       ContentType: file.type,
       Body: file
       };
       bucket.upload(params, function(err, data) {
       results.innerHTML = err ? 'ERROR!' : 'UPLOADED.';
       });
       } else {
       results.innerHTML = 'Nothing to upload.';
       }    }
      </script>
      <body>
       <input type="file" id="file-chooser" />
       <input type="button" onclick="upload()" value="Upload to S3">
       <div id="results"></div>
      </body>
      

2
Không ai có thể sử dụng "Nhận dạngPoolId" của tôi để tải tệp lên nhóm S3 của tôi. Làm thế nào là giải pháp này ngăn bất kỳ bên thứ 3 nào chỉ sao chép "Nhận dạngPoolId" của tôi và tải nhiều tệp lên nhóm S3 của tôi?
Sahil

1
stackoverflow.com/users/4535741/sahil Bạn có thể ngăn tải lên dữ liệu / tệp từ các tên miền khác bằng cách đặt cài đặt CORS phù hợp cho nhóm S3. Vì vậy, ngay cả khi bất kỳ ai truy cập id nhóm nhận dạng của bạn, họ không thể thao tác các tệp xô s3 của bạn.
Nilesh Pawar

2

Nếu bạn không có bất kỳ mã phía máy chủ nào, bảo mật của bạn phụ thuộc vào bảo mật của quyền truy cập vào mã JavaScript của bạn ở phía máy khách (tức là mọi người có mã có thể tải lên một cái gì đó).

Vì vậy, tôi khuyên bạn, chỉ cần tạo một thùng S3 đặc biệt có thể ghi công khai (nhưng không thể đọc được), vì vậy bạn không cần bất kỳ thành phần nào được ký ở phía máy khách.

Tên nhóm (ví dụ GUID) sẽ là cách bảo vệ duy nhất của bạn trước các video tải lên độc hại (nhưng kẻ tấn công tiềm năng không thể sử dụng nhóm của bạn để truyền dữ liệu, vì nó chỉ được ghi cho anh ta)


1

Đây là cách bạn tạo một tài liệu chính sách bằng cách sử dụng nút và serverless

"use strict";

const uniqid = require('uniqid');
const crypto = require('crypto');

class Token {

    /**
     * @param {Object} config SSM Parameter store JSON config
     */
    constructor(config) {

        // Ensure some required properties are set in the SSM configuration object
        this.constructor._validateConfig(config);

        this.region = config.region; // AWS region e.g. us-west-2
        this.bucket = config.bucket; // Bucket name only
        this.bucketAcl = config.bucketAcl; // Bucket access policy [private, public-read]
        this.accessKey = config.accessKey; // Access key
        this.secretKey = config.secretKey; // Access key secret

        // Create a really unique videoKey, with folder prefix
        this.key = uniqid() + uniqid.process();

        // The policy requires the date to be this format e.g. 20181109
        const date = new Date().toISOString();
        this.dateString = date.substr(0, 4) + date.substr(5, 2) + date.substr(8, 2);

        // The number of minutes the policy will need to be used by before it expires
        this.policyExpireMinutes = 15;

        // HMAC encryption algorithm used to encrypt everything in the request
        this.encryptionAlgorithm = 'sha256';

        // Client uses encryption algorithm key while making request to S3
        this.clientEncryptionAlgorithm = 'AWS4-HMAC-SHA256';
    }

    /**
     * Returns the parameters that FE will use to directly upload to s3
     *
     * @returns {Object}
     */
    getS3FormParameters() {
        const credentialPath = this._amazonCredentialPath();
        const policy = this._s3UploadPolicy(credentialPath);
        const policyBase64 = new Buffer(JSON.stringify(policy)).toString('base64');
        const signature = this._s3UploadSignature(policyBase64);

        return {
            'key': this.key,
            'acl': this.bucketAcl,
            'success_action_status': '201',
            'policy': policyBase64,
            'endpoint': "https://" + this.bucket + ".s3-accelerate.amazonaws.com",
            'x-amz-algorithm': this.clientEncryptionAlgorithm,
            'x-amz-credential': credentialPath,
            'x-amz-date': this.dateString + 'T000000Z',
            'x-amz-signature': signature
        }
    }

    /**
     * Ensure all required properties are set in SSM Parameter Store Config
     *
     * @param {Object} config
     * @private
     */
    static _validateConfig(config) {
        if (!config.hasOwnProperty('bucket')) {
            throw "'bucket' is required in SSM Parameter Store Config";
        }
        if (!config.hasOwnProperty('region')) {
            throw "'region' is required in SSM Parameter Store Config";
        }
        if (!config.hasOwnProperty('accessKey')) {
            throw "'accessKey' is required in SSM Parameter Store Config";
        }
        if (!config.hasOwnProperty('secretKey')) {
            throw "'secretKey' is required in SSM Parameter Store Config";
        }
    }

    /**
     * Create a special string called a credentials path used in constructing an upload policy
     *
     * @returns {String}
     * @private
     */
    _amazonCredentialPath() {
        return this.accessKey + '/' + this.dateString + '/' + this.region + '/s3/aws4_request';
    }

    /**
     * Create an upload policy
     *
     * @param {String} credentialPath
     *
     * @returns {{expiration: string, conditions: *[]}}
     * @private
     */
    _s3UploadPolicy(credentialPath) {
        return {
            expiration: this._getPolicyExpirationISODate(),
            conditions: [
                {bucket: this.bucket},
                {key: this.key},
                {acl: this.bucketAcl},
                {success_action_status: "201"},
                {'x-amz-algorithm': 'AWS4-HMAC-SHA256'},
                {'x-amz-credential': credentialPath},
                {'x-amz-date': this.dateString + 'T000000Z'}
            ],
        }
    }

    /**
     * ISO formatted date string of when the policy will expire
     *
     * @returns {String}
     * @private
     */
    _getPolicyExpirationISODate() {
        return new Date((new Date).getTime() + (this.policyExpireMinutes * 60 * 1000)).toISOString();
    }

    /**
     * HMAC encode a string by a given key
     *
     * @param {String} key
     * @param {String} string
     *
     * @returns {String}
     * @private
     */
    _encryptHmac(key, string) {
        const hmac = crypto.createHmac(
            this.encryptionAlgorithm, key
        );
        hmac.end(string);

        return hmac.read();
    }

    /**
     * Create an upload signature from provided params
     * https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html#signing-request-intro
     *
     * @param policyBase64
     *
     * @returns {String}
     * @private
     */
    _s3UploadSignature(policyBase64) {
        const dateKey = this._encryptHmac('AWS4' + this.secretKey, this.dateString);
        const dateRegionKey = this._encryptHmac(dateKey, this.region);
        const dateRegionServiceKey = this._encryptHmac(dateRegionKey, 's3');
        const signingKey = this._encryptHmac(dateRegionServiceKey, 'aws4_request');

        return this._encryptHmac(signingKey, policyBase64).toString('hex');
    }
}

module.exports = Token;

Đối tượng cấu hình được sử dụng được lưu trữ trong SSM Parameter Store và trông như thế này

{
    "bucket": "my-bucket-name",
    "region": "us-west-2",
    "bucketAcl": "private",
    "accessKey": "MY_ACCESS_KEY",
    "secretKey": "MY_SECRET_ACCESS_KEY",
}

0

Nếu bạn sẵn sàng sử dụng dịch vụ của bên thứ 3, auth0.com hỗ trợ tích hợp này. Dịch vụ auth0 trao đổi xác thực dịch vụ SSO của bên thứ 3 cho mã thông báo phiên tạm thời AWS sẽ giới hạn quyền.

Xem: https://github.com/auth0-samples/auth0-s3-sample/
và tài liệu auth0.


1
Theo tôi hiểu - bây giờ chúng ta có Cognito cho điều đó?
Vitaly Zdanevich
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.