基于AWS Cognito的无服务器React应用用户认证技术问询
Great to hear you've already got your serverless web app up and running with S3 for static hosting, Lambda for backend logic, and API Gateway as your entry point. Since you've already created a Cognito User Pool, let's walk through the key steps to integrate it into your setup to add secure authentication:
First, you'll need to set up an app client within your existing user pool (this is what your frontend will communicate with):
- Head to the Cognito Console, select your user pool, and navigate to App integration > App clients and analytics.
- Create a new app client: uncheck Generate client secret (static frontends like S3 can't securely store secrets), give it a name, and save.
- Next, go to App integration > Domain name to set up a Cognito hosted domain (this is the login UI URL you mentioned testing, like
https://your-pool-name.auth.your-region.amazoncognito.com). - Under App integration > App client settings, enable OAuth 2.0:
- Add your S3 static site URL as an Allowed callback URL and Allowed sign-out URL (e.g.,
https://your-bucket-name.s3.your-region.amazonaws.comor your custom domain if you've set one up). - Select authorization types: for static frontends, Authorization code grant with PKCE is the most secure (avoid implicit grant if possible).
- Check the OAuth scopes you need (e.g.,
openid,email,profileto access user identity data).
- Add your S3 static site URL as an Allowed callback URL and Allowed sign-out URL (e.g.,
You have two main options here—using the Cognito Hosted UI (quickest setup) or integrating directly with the AWS SDK/Amplify Library for more control:
Option A: Use the Cognito Hosted UI
Just add a login button to your frontend that redirects users to the Cognito login URL. You can construct the URL like this:
https://your-cognito-domain/login?response_type=code&client_id=your-app-client-id&redirect_uri=https://your-s3-site-url&code_challenge=your-pkce-code-challenge&code_challenge_method=S256
(PKCE is required for authorization code grant with public clients—you'll need to generate the code challenge/verifier on the frontend before redirecting.)
After successful login, Cognito will redirect back to your S3 site with an authorization code. Your frontend can then exchange this code for ID/access tokens via Cognito's token endpoint.
Option B: Use AWS Amplify Library (Simpler for Full Integration)
Add the Amplify JS library to your frontend (via CDN or npm), then configure it to use your Cognito pool:
<!-- Add Amplify via CDN --> <script src="https://cdn.amplifyjs.com/lib/amplify-5.0.0.min.js"></script> <script> // Initialize Amplify Amplify.configure({ Auth: { region: 'your-aws-region', userPoolId: 'your-user-pool-id', userPoolWebClientId: 'your-app-client-id', oauth: { domain: 'your-cognito-domain', scope: ['openid', 'email', 'profile'], redirectSignIn: 'https://your-s3-site-url', redirectSignOut: 'https://your-s3-site-url', responseType: 'code' // Uses PKCE automatically } } }); // Example login function async function handleLogin() { try { const user = await Amplify.Auth.signInWithRedirect(); // After redirect, call Amplify.Auth.currentAuthenticatedUser() to get user details } catch (err) { console.error('Login error:', err); } } // Example logout function async function handleLogout() { await Amplify.Auth.signOut(); } </script>
Now lock down your API Gateway so only authenticated users can access your Lambda functions:
- Go to the API Gateway Console, select your API, and navigate to Authorizers > Create New Authorizer.
- Choose Cognito as the type, select your user pool, and enter your app client ID as the Token Source (usually
Authorizationheader). - Save the authorizer, then go to each of your API resources/methods (e.g., GET /api/data) and set the Authorization dropdown to your new Cognito authorizer.
- Deploy your API changes to make them live.
Verify User Identity in Lambda
In your Lambda function, you can access the authenticated user's details from the request context, or verify the token directly for extra security:
const { CognitoJwtVerifier } = require("aws-jwt-verify"); // Initialize verifier const verifier = CognitoJwtVerifier.create({ userPoolId: "your-user-pool-id", tokenUse: "access", // Use "id" if you're passing the ID token clientId: "your-app-client-id", }); exports.handler = async (event) => { try { // Extract token from Authorization header const authHeader = event.headers.Authorization; const token = authHeader?.split(" ")[1]; if (!token) throw new Error("No token provided"); // Verify and decode the token const userData = await verifier.verify(token); // Use user data in your logic (e.g., userData.email, userData.sub) return { statusCode: 200, body: JSON.stringify({ message: "Hello authenticated user!", user: userData }) }; } catch (err) { return { statusCode: 401, body: JSON.stringify({ message: "Unauthorized access" }) }; } };
Since your S3 frontend and API Gateway are separate domains, you'll need to configure CORS correctly:
- S3 Bucket: Go to your bucket's Permissions > Cross-origin resource sharing (CORS) and add a policy that allows your API Gateway domain, and includes the
Authorizationheader:[ { "AllowedHeaders": ["*"], "AllowedMethods": ["GET", "POST", "OPTIONS"], "AllowedOrigins": ["https://your-api-gateway-url"], "ExposeHeaders": [] } ] - API Gateway: For each method, enable CORS and set Allowed Origins to your S3 site URL, and check Authorization under Allowed Headers. Deploy the API after making changes.
- Visit your S3 static site and click the login button—you should be redirected to the Cognito Hosted UI.
- Log in with a test user you created in your Cognito pool.
- After redirecting back to your site, your frontend should have valid tokens.
- Send a request to your API Gateway endpoint with the
Authorization: Bearer <access-token>header—your Lambda should return a successful response with user data. - Try accessing the API without a token to confirm it returns a 401 Unauthorized error.
内容的提问来源于stack exchange,提问作者Mehran

