我有一个使用 aws-amplify 并进行身份验证的代码。
Code:
signRequest(host: any, path: any, method: any, accessKey: any, secretKey: any, region: any, service: any) {
const amzDate = this.getAmzDate();
const dateStamp = this.getDate(); // Prepare canonical request
const canonicalURI = path;
const canonicalQueryString = '';
const canonicalHeaders = `host:${host}\n` + `x-amz-date:${amzDate}\n`;
const signedHeaders = 'host;x-amz-date';
const payloadHash = CryptoJS.SHA256('').toString(CryptoJS.enc.Hex);
const canonicalRequest = `${method}\n${canonicalURI}\n${canonicalQueryString}\n${canonicalHeaders}\n${signedHeaders}\n${payloadHash}`;
console.log("Canonical Request:", canonicalRequest);
// String to sign
const algorithm = 'AWS4-HMAC-SHA256';
const credentialScope = `${dateStamp}/${region}/${service}/aws4_request`;
const stringToSign = `${algorithm}\n${amzDate}\n${credentialScope}\n${CryptoJS.SHA256(canonicalRequest).toString(CryptoJS.enc.Hex)}`;
console.log("String to Sign:", stringToSign);
// Signature
const signingKey = this.getSignatureKey(secretKey, dateStamp, region, service);
const signature = CryptoJS.HmacSHA256(stringToSign, signingKey).toString(CryptoJS.enc.Hex);
console.log("Calculated Signature:", signature);
// Authorization header
const authorizationHeader = `${algorithm} Credential=${accessKey}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;
console.log("authorization success",authorizationHeader)
return {
'Content-Type': 'text/plain',
'x-amz-date': amzDate,
'Authorization': authorizationHeader
// 'x-amz-security-token': sessionToken // Optional, if using session-based access
};
}
getSignatureKey(key: string, dateStamp: string | CryptoJS.lib.WordArray, region: string | CryptoJS.lib.WordArray, service: string | CryptoJS.lib.WordArray) {
const kDate = CryptoJS.HmacSHA256(dateStamp, "AWS4" + key);
const kRegion = CryptoJS.HmacSHA256(region, kDate);
const kService = CryptoJS.HmacSHA256(service, kRegion);
const kSigning = CryptoJS.HmacSHA256("aws4_request", kService);
console.log("k signing key",kSigning)
console.log("get Signature key:", this.getSignatureKey);
return kSigning;
// Define your AWS and API details
host = 'https://2ydk2p26dbv2ak5fygphvcb6ey0dzrzm.lambda-url.us-east-1.on.aws/';
path = '/';
method = 'POST';
region = 'us-east-1';
service = 'lambda';
accessKey = '****';
secretKey = '****';
// sessionToken = ''; // Generate signed headers
new_headers = this.signRequest(this.host, this.path, this.method, this.accessKey, this.secretKey,this.region, this.service);
当我运行它时,我收到此错误:
从源“https://function-url-ver2-1.d2qo24bmjgejow.amplifyapp.com”访问“https://2ydk2p26dbv2ak5fygphvcb6ey0dzrzm.lambda-url.us-east-1.on.aws/”处的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:否请求的资源上存在“Access-Control-Allow-Origin”标头。
我应该改变什么才能做到这一点?
问题是您的 lambda 没有发送 CORS(跨源资源共享)标头作为对浏览器完成的预检(选项)调用的响应。您可以在此处阅读有关 CORS 确切规则的更多信息(https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)。
您可以在 lambda 控制台中设置 cors 配置,如果您使用 cdk 部署函数 url,它是 props 中的一个字段,如果您使用普通的 cloudformation,它也是函数 url 配置中的一个字段。
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-url.html
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.FunctionUrl.html
您需要添加至少一个允许的来源,如果您想允许所有来源,您可以使用*
您可能还需要添加允许的 Http 方法和随请求发送的标头。
另一种解决方案是通过与您的 amplify 应用程序相同的 Cloudfront 发行版来提供此 lambda 函数 url。他们将拥有相同的主机并且不需要 CORS