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 เริ่มทำงานแล้ว)
ฉันหวังว่าคำตอบที่ฉันหามาได้นี้จะช่วยใครบางคนที่มีปัญหาเดียวกันได้
