本地SAM部署Lambda对接AWS Cognito:传递用户信息需求咨询
Let's break this down into actionable steps—from getting your frontend to send the token, to making sure your local API accepts it, and even validating the token in your Lambda if you need to.
1. Frontend: Attach Cognito ID Token to Request Headers
First, you need to grab the valid Cognito ID Token from your authenticated user session and include it in the Authorization header when calling your local SAM API.
If you're using AWS Amplify (super common for Cognito integrations), here's a quick example:
import { Auth } from 'aws-amplify'; async function callLocalLambda() { try { // Get the current user's active session const session = await Auth.currentSession(); const idToken = session.getIdToken().getJwtToken(); // Call your local SAM API endpoint const response = await fetch('http://localhost:3000/your-api-path', { method: 'GET', // Adjust to POST/PUT/DELETE as needed headers: { 'Authorization': idToken, // This is the critical header carrying user info 'Content-Type': 'application/json' } }); const data = await response.json(); console.log('Lambda response:', data); } catch (err) { console.error('Error calling local API:', err); } }
If you're not using Amplify, you can use the AWS Cognito SDK directly to fetch the token from the user pool session—just make sure you pull the ID Token (not Access Token, unless your use case specifically requires it) and format the header correctly.
2. Configure SAM to Allow Authorization Headers (Fix CORS)
Chances are your frontend runs on a different port than your local SAM API (e.g., frontend on localhost:3000, SAM on localhost:3000 is rare). This triggers CORS issues unless you explicitly whitelist the Authorization header in your SAM template.
Update your template.yml to include CORS configuration that permits the header:
Resources: YourApi: Type: AWS::Serverless::Api Properties: StageName: dev Cors: AllowMethods: "'GET,POST,PUT,DELETE,OPTIONS'" AllowHeaders: "'Content-Type,Authorization'" # Add Authorization here AllowOrigin: "'http://localhost:3000'" # Replace with your actual frontend URL YourLambdaFunction: Type: AWS::Serverless::Function Properties: CodeUri: your-lambda-code/ Handler: app.lambdaHandler Events: ApiEvent: Type: Api Properties: RestApiId: !Ref YourApi Path: /your-api-path Method: get
After updating the template, restart your local SAM API with sam local start-api to apply the changes.
3. (Optional) Validate the Cognito Token in Your Local Lambda
When running Lambda locally, AWS doesn’t automatically validate the Cognito token like it does in the cloud. If you want to test your auth logic end-to-end, you can add token validation using the jsonwebtoken and jwks-rsa libraries.
Step 3.1: Install Dependencies
In your Lambda project folder, run:
npm install jsonwebtoken jwks-rsa
Step 3.2: Add Token Validation Logic
Here’s a reusable validation function you can drop into your Lambda code:
const jwt = require('jsonwebtoken'); const jwksClient = require('jwks-rsa'); // Configure with your Cognito user pool details const client = jwksClient({ jwksUri: 'https://cognito-idp.<your-region>.amazonaws.com/<your-user-pool-id>/.well-known/jwks.json' }); function getKey(header, callback) { client.getSigningKey(header.kid, function(err, key) { const signingKey = key.getPublicKey(); callback(null, signingKey); }); } async function validateToken(token) { return new Promise((resolve, reject) => { jwt.verify(token, getKey, { issuer: 'https://cognito-idp.<your-region>.amazonaws.com/<your-user-pool-id>', algorithms: ['RS256'] }, function(err, decoded) { if (err) reject(err); else resolve(decoded); }); }); } // Example Lambda handler exports.lambdaHandler = async (event) => { try { // Extract the Authorization header from the request const authHeader = event.headers.Authorization; if (!authHeader) { return { statusCode: 401, body: JSON.stringify({ message: 'Authorization header missing' }) }; } // Validate the token and get user details const decodedUser = await validateToken(authHeader); console.log('Authenticated user:', decodedUser); // Your core Lambda logic here return { statusCode: 200, body: JSON.stringify({ message: 'Success', user: decodedUser }) }; } catch (err) { console.error('Token validation failed:', err); return { statusCode: 403, body: JSON.stringify({ message: 'Invalid or expired token' }) }; } };
Replace <your-region> and <your-user-pool-id> with your actual Cognito values. This checks the token’s signature, expiration, and issuer—matching the validation the cloud API Gateway performs.
4. Test It Out
- Ensure your frontend is logged in (so you have a valid Cognito token).
- Restart your SAM local API with
sam local start-api. - Trigger your frontend function that calls the local API—you’ll see the
Authorizationheader in the Lambda’sevent.headers, and if you added validation, the decoded user info will be logged.
That’s all! You’re now passing Cognito user information to your local Lambda via the Authorization header.
内容的提问来源于stack exchange,提问作者dmi88

