-
Notifications
You must be signed in to change notification settings - Fork 26.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Edge Runtime and AWS SDK credentials #65769
Comments
I'm trying to do the same thing. I've been paying a hefty "Next tax" lately. Looks like this is something we simply can't do. Middleware for auth doesn't seem like that weird of a use case... |
How are you creating the lambdas? Are you using CDK or similar? Have you tried configuring your Lambda@Edge with an IAM Execution Role that has access to SSM as describe in this blog post? |
@gardner yes of course. I use cdk everywhere. All the necessary permissions already set. It's not about the SSM itself, but rather about total inability to use AWS SDK in a middleware (because it depends heavily on nodejs api). I ended up removing AWS SDK from the middleware altogether. They were replaced with export default async function middleware(request: NextRequest) {
const {url, cookies} = request
const path = request.nextUrl.pathname
// Get all the tokens
const accessToken = cookies.get('accessToken')?.value
const idToken = cookies.get('idToken')?.value
const refreshToken = cookies.get('refreshToken')?.value
const isAuthPage =
path.startsWith('/confirm-register') ||
path.startsWith('/forgot-password') ||
path.startsWith('/login') ||
path.startsWith('/register') ||
path.startsWith('/reset-password')
const isDashboard = path.startsWith('/dashboard')
let isSessionValid = false
let isTokenExpired = false
// Redirect to dashboard if user is already logged in
if (accessToken && idToken && refreshToken) {
const IdToken = new CognitoIdToken({ IdToken: idToken})
const AccessToken = new CognitoAccessToken({ AccessToken: accessToken })
const RefreshToken = new CognitoRefreshToken({ RefreshToken: refreshToken })
const cachedSession = new CognitoUserSession({
IdToken,
AccessToken,
RefreshToken
})
isSessionValid = cachedSession.isValid()
isTokenExpired = tokenExpired(IdToken)
}
// We have a valid cognito session, redirect user to dashboard
if (isAuthPage) {
if (isSessionValid) {
return NextResponse.redirect(new URL('/dashboard', url))
}
return NextResponse.next()
}
// In case of dashboard, check if session is valid and token not expired yet
if (isDashboard) {
if (isSessionValid) {
if (isTokenExpired) {
// Update all the tokens
return await getNewTokens(url, refreshToken)
}
// Do nothing, just procceed with request
return NextResponse.next()
}
}
return NextResponse.redirect(new URL('/logout', url)) Plus some manual checks. const tokenExpired = (token: CognitoIdToken): boolean => {
return new Date(token.getExpiration() * 1000) <= new Date()
} I moved AWS SDK Cognito client to // Receive new tokens and update cookies
const response = await fetch(new URL('/api/refresh-token', base), {
headers: {
'Content-Type': 'application/json',
cookie: `refreshToken=${refreshToken}`
}
}) This solution is far from ideal but more or less solves the problem. Of course it would be nice to use SDK directly from the middleware without having to move to it to the API. |
Link to the code that reproduces this issue
https://github.com/r007/next-aws-sdk-middleware-issue
To Reproduce
For example, if I want to get a variable from AWS Systems Manager Parameter Store, I can use this code:
It'll throw a
Credential is missing
error, because the edge runtime can't get AWS credentials from local file.Current vs. Expected behavior
Hi guys,
I want to use AWS SDK API in my next.js middleware to get parameters. The reason for this is that Edge@Lambda doesn't support environment variables, so I have to use AWS Parameter Store instead.
Next.js Edge runtime doesn't work with AWS SDK at all. Simply because it uses node.js API behind the scene to get credentials (access key + secret access key). It reads a local file with credentials, but since the Edge runtime can't read anything, it fails to get access key + secret key needed to make an API call.
Any suggestions? Possible solutions?
Best regards,
Sergey
Provide environment information
Node.js v20.12.2 Operating System: Platform: linux Arch: x64 Version: #58-Ubuntu SMP Thu Oct 13 08:03:55 UTC 2022 Available memory (MB): 7911 Available CPU cores: 8 Binaries: Node: 20.12.2 npm: 10.7.0 Yarn: 1.22.22 pnpm: N/A Relevant Packages: next: 14.2.3 // Latest available version is detected (14.2.3). eslint-config-next: N/A react: 18.3.1 react-dom: 18.3.1 typescript: N/A Next.js Config: output: N/A
Which area(s) are affected? (Select all that apply)
Middleware, Runtime
Which stage(s) are affected? (Select all that apply)
next dev (local), next build (local), next start (local), Vercel (Deployed), Other (Deployed)
Additional context
I'm trying to implement authentication with AWS Cognito inside the middleware + token renewal.
The text was updated successfully, but these errors were encountered: