简体   繁体   中英

How to setup AWS-SDK credentials in NextJS

I need to upload some files to S3 from a NextJs application. Since it is server side I am under the impression simply setting environment variables should work but it doesn't. I know there are other alternative like assigning a role to EC2 but I want to use accessKeyID and secretKey.

This is my next.config.js

module.exports = {
  env: {
    //..others
    AWS_ACCESS_KEY_ID: process.env.AWS_ACCESS_KEY_ID
  },
  serverRuntimeConfig: {
    //..others
    AWS_SECRET_ACCESS_KEY: process.env.AWS_SECRET_ACCESS_KEY
  }
}

This is my config/index.js

export default {
  //...others
  awsClientID: process.env. AWS_ACCESS_KEY_ID,
  awsClientSecret: process.env.AWS_SECRET_ACCESS_KEY
}

This is how I use in my code:

import AWS from 'aws-sdk'
import config from '../config'

AWS.config.update({
  accessKeyId: config.awsClientID,
  secretAccessKey: config.awsClientSecret,
});

const S3 = new AWS.S3()

const params = {
  Bucket: "bucketName",
  Key: "some key",
  Body: fileObject,
  ContentType: fileObject.type,
  ACL: 'public-read'
}

await S3.upload(params).promise()

I am getting this error: Unhandled Rejection (CredentialsError): Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1

If I hard code the credentials in code, it works fine.

How can I make it work correctly?

Looks like the Vercel docs are currently outdated (AWS SDK V2 instead of V3). You can pass the credentials object to the AWS service when you instantiate it. Use an environment variable that is not reserved by adding the name of your app to it for example.

.env.local

YOUR_APP_AWS_ACCESS_KEY_ID=[your key]
YOUR_APP_AWS_SECRET_ACCESS_KEY=[your secret]

Add these env variables to your Vercel deployment settings (or Netlify, etc) and pass them in when you start up your AWS service client.

import { S3Client } from '@aws-sdk/client-s3'

...

const s3 = new S3Client({
  region: 'us-east-1',
  credentials: {
    accessKeyId: process.env.TRENDZY_AWS_ACCESS_KEY_ID ?? '',
    secretAccessKey: process.env.TRENDZY_AWS_SECRET_ACCESS_KEY ?? '',
  },
})

(note: undefined check so Typescript stays happy)

If I'm not mistaken, you want to make AWS_ACCESS_KEY_ID into a runtime variable as well. Currently, it is a build time variable, which won't be accessible in your node application.

// replace this 
env: {
    //..others
    AWS_ACCESS_KEY_ID: process.env.AWS_ACCESS_KEY_ID
  },

// with this
module.exports = {
  serverRuntimeConfig: {
    //..others
    AWS_ACCESS_KEY_ID: process.env.AWS_ACCESS_KEY_ID
  }
}

Reference: https://nextjs.org/docs/api-reference/next.config.js/environment-variables

are you possibly hosting this app via vercel? As per vercel docs, some env variables are reserved by vercel.

https://vercel.com/docs/concepts/projects/environment-variables#reserved-environment-variables

AWS_ACCESS_KEY_ID

AWS_SECRET_ACCESS_KEY

Maybe that's the reason why it is not getting those env vars

I was able to workaround this by adding my custom env variables into.env.local and then calling for those variables

AWS.config.update({
 'region': 'us-east-1',
 'credentials': {
   'accessKeyId': process.env.MY_AWS_ACCESS_KEY,
   'secretAccessKey': process.env.MY_AWS_SECRET_KEY
 }
});

As last step would need to add these into vercel UI

obviously not ideal solution and not recommended by AWS.

https://vercel.com/support/articles/how-can-i-use-aws-sdk-environment-variables-on-vercel

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM