ค้นหาเว็บไซต์

javascript - AWS S3Client โหลดข้อมูลประจำตัวไม่ถูกต้อง


ฉันมีปัญหาเกี่ยวกับ S3 Client จาก aws sdk v3 :

หากฉันใช้ S3Client ตามที่ระบุในเอกสาร โดยใช้ข้อมูลรับรองที่ให้มาผ่านตัวแปรสภาพแวดล้อม ฉันจะได้รับข้อผิดพลาด The AWS Access Key Id you provided does not exist in our records.

ตอนแรกฉันคิดว่ามันเป็นเพราะฉันไม่ได้ใช้ AWS_ACCESS_KEY_ID ที่ถูกต้อง แต่การเพิ่มบรรทัดนี้ทันทีหลังจากการสร้างไคลเอนต์ก็แก้ปัญหาได้ และบันทึกค่าที่ถูกต้อง:

s3.config.credentials().then(console.log)

สิ่งที่ทำให้ฉันรบกวนใจที่สุดคือความจริงที่ว่าถ้าฉันเรียกบรรทัดนี้จากที่อื่น (เช่น: ในฟังก์ชันแบบอะซิงค์) มันก็ไม่แก้ปัญหา

  • ทำไมการเรียกฟังก์ชันแบบอะซิงค์นี้ถึงแก้ไขการทำงานที่เหลือได้?
  • มันแก้ไขเฉพาะไคลเอนต์ชั่วคราวเท่านั้นหรือ? (ไคลเอนต์ยังคงถูกสร้างขึ้นสำหรับการเรียกใช้งานหลายฟังก์ชัน)
  • สัญญาสามารถสิ้นสุดช้าเกินไปได้หรือไม่: หลังจากการโทรครั้งแรกของลูกค้า?
  • ทำไมมันถึงไม่ทำงานเมื่อเรียกก่อนการเรียก s3 โดยตรง (ไม่ว่าจะมีหรือไม่มี await)?

นี่คือโค้ดของฉัน :

const s3Config: S3ClientConfig = {}
s3Config.endpoint = new HttpRequest({...} as Endpoint) // used with a local s3 server
const s3 = new S3Client(s3Config);

// this is the hack
s3.config.credentials().then(console.log)

export const upload = async (...) => {
    // here it does not work
    // await s3.config.credentials().then(console.log)

    const streamUpload = new Upload({client: s3,...})
    return await streamUpload.done()
}


export const getTempLink = async (...) => {
    // here it does not work
    // await s3.config.credentials().then(console.log)

    //* Get the pre-signed url
    const command = new GetObjectCommand({Bucket,Key})
    return await getSignedUrl(s3 as any, command as any, { expiresIn })
}

ขอบคุณสำหรับความช่วยเหลือของคุณ!

คำตอบ #1

ฉันมีปัญหาคล้ายๆ กับนั้น

ข้อแตกต่างอันดับแรกระหว่าง aws-sdk กับ aws-sdk/client-s3

ปัญหาของฉันคือในไฟล์ .env ชื่อคีย์เป็นแบบนี้

ACCESS_KEY_ID, 
SECRET_ACCESS_KEY, 
AWS_SESSION_TOKEN

นั่นใช้ไม่ได้ ดังนั้นฉันจึงเปลี่ยนชื่อดังนี้และพร้อมใช้งาน มันใช้ข้อมูลรับรองแล้ว

AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY,
AWS_SESSION_TOKEN,

โปรดจำไว้ว่า AWS มี ลำดับความสำคัญ สำหรับข้อมูลประจำตัว

คำตอบ #2

นี่คือสิ่งไม่กี่อย่างที่ฉันพบเพื่อตอบคำถามของฉัน:

ดังที่กล่าวในคำถาม เส้นที่ทำให้มันทำงานคือ

await s3.config.credentials()

ทำไมการเรียกฟังก์ชันแบบอะซิงค์นี้ถึงแก้ไขการทำงานที่เหลือได้?

ตามที่ตอบไว้ที่นี่ การใช้ตัวสร้างบริการ คุณสามารถมีการตั้งค่า AWS หลายรายการได้ นอกจากนี้ ตามที่ Programmer89 ระบุ ลำดับความสำคัญมีความสำคัญ แต่มีข้อแม้:
ไคลเอนต์ AWS จะไม่โหลดการตั้งค่าในทันที แต่จะโหลดเฉพาะเมื่อจำเป็นเท่านั้น

การใช้ฟังก์ชัน config.credentials() จะช่วยให้การโหลดการตั้งค่าทำได้ทันที

ทำไมมันถึงไม่ทำงานเมื่อเรียกก่อนการเรียก s3 โดยตรง (ไม่ว่าจะมี await หรือไม่)?

การกำหนดค่านี้จำเป็นต้องถูกโหลดทันที เพราะ AWS SDK เดียวกันถูกใช้กับการกำหนดค่าอื่น ๆ (โดยใช้จุดเชื่อมต่อ DynamoDB และ S3 ที่กำหนดเองสำหรับการทดสอบในเครื่อง)

ถ้าเรียกใช้งานในเวลาใด ๆ หลังจากนั้น ดูเหมือนว่าจะใช้ตัวแปรสภาพแวดล้อมตัวสุดท้ายที่ใช้กับ SDK นั้น มากกว่าตัวแปรที่มีอยู่ในเวลาที่เรียกตัวสร้าง

มันแก้ไขเฉพาะไคลเอนต์ชั่วคราวหรือไม่? (ไคลเอนต์ยังคงถูกสร้างขึ้นสำหรับการเรียกฟังก์ชันหลายครั้ง)

ฉันไม่แน่ใจ อาจจะมีหรือไม่มีก็ได้ แต่เรามีปัญหานั้นแค่สำหรับการทดสอบในพื้นที่เท่านั้น

ในการผลิต กระบวนการเหล่านั้นจะแยกออกจากกันได้ดีกว่า ในเครื่องลูกข่าย ภายในเครื่องไคลเอ็นต์จะไม่ได้ถูกสร้างตัวตนคงที่เกินกว่าหนึ่งครั้งที่เรียกใช้ ดังนั้นฉันจึงไม่ได้มองต่อไป

สัญญาสามารถสิ้นสุดช้าเกินไปได้หรือไม่: หลังจากการโทรครั้งแรกจากลูกค้า?

ดูเหมือนไม่สำคัญ ตราบใดที่ไคลเอนต์เริ่มโหลดการตั้งค่า (เช่น: Promise เริ่มทำงานแล้ว)

ฉันหวังว่าคำตอบที่ฉันหามาได้นี้จะช่วยใครบางคนที่มีปัญหาเดียวกันได้

บทความที่เกี่ยวข้อง