如何在不登录的情况下验证用户凭证?基于AWS Amplify
Great question! You're right that Auth.signIn() will fully authenticate the user and replace any existing session, which isn't ideal if you just want to validate credentials without logging them in. Here are two practical approaches to solve this:
Auth.signIn()后立即登出 This is the simplest approach—you can leverage the existing Auth.signIn() method, then immediately sign the user out if credentials are valid. This works because Auth.signIn() will throw an error if the credentials are invalid, so we can use a try/catch block to handle validation.
代码示例:
async function validateUserCredentials(email, password) { let isCredentialsValid = false; try { // Attempt to sign in—this will throw an error if credentials are invalid const authenticatedUser = await Auth.signIn(email, password); // If we reach this line, credentials are valid. Sign out immediately. await Auth.signOut(); isCredentialsValid = true; } catch (error) { // Handle invalid credentials or other errors (e.g., user not found, account locked) console.error('Credential validation failed:', error.message); isCredentialsValid = false; } return isCredentialsValid; }
注意事项:
- Impact on existing sessions: If there's already a logged-in user, calling
Auth.signIn()will replace their session temporarily before signing out. This means the original user will be logged out after this process. If you need to preserve the current user's session, skip to the next approach. - Cognito logs: This will generate a login event in your Cognito user pool logs, even though the user is immediately signed out.
If you need to avoid disrupting the current user's session or don't want temporary login records, you can create a custom Lambda function that uses Cognito's AdminInitiateAuth API to validate credentials without creating a user session.
步骤1:创建Lambda函数
Here's a Node.js Lambda example that checks credentials using the USER_PASSWORD_AUTH auth flow:
const AWS = require('aws-sdk'); const cognito = new AWS.CognitoIdentityServiceProvider(); exports.handler = async (event) => { const { email, password, userPoolId, clientId } = event; const authParams = { AuthFlow: 'USER_PASSWORD_AUTH', ClientId: clientId, UserPoolId: userPoolId, AuthParameters: { USERNAME: email, PASSWORD: password } }; try { // This call will succeed only if credentials are valid await cognito.adminInitiateAuth(authParams).promise(); return { statusCode: 200, body: JSON.stringify({ valid: true }) }; } catch (error) { console.error('Validation error:', error); return { statusCode: 401, body: JSON.stringify({ valid: false, message: error.message }) }; } };
步骤2:配置Lambda权限
Make sure your Lambda's IAM role has a policy allowing the cognito-idp:AdminInitiateAuth action on your user pool. Example policy:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "cognito-idp:AdminInitiateAuth", "Resource": "arn:aws:cognito-idp:YOUR_REGION:YOUR_ACCOUNT_ID:userpool/YOUR_USER_POOL_ID" } ] }
步骤3:前端调用Lambda(via API Gateway)
Expose the Lambda via API Gateway, then call it from your frontend using Amplify's API module:
import { API } from 'aws-amplify'; async function validateCredentials(email, password) { try { const response = await API.post('yourApiGatewayName', '/validate-credentials', { body: { email, password, userPoolId: 'YOUR_USER_POOL_ID', clientId: 'YOUR_APP_CLIENT_ID' } }); return response.valid; } catch (error) { console.error('Failed to call validation API:', error); return false; } }
优点:
- No impact on the current logged-in user's session.
- No temporary login records in Cognito.
- More flexible for custom validation logic (e.g., checking account status alongside credentials).
内容的提问来源于stack exchange,提问作者Zero3X

