英文:
AWS : Calling Rest API with IAM authentication from Node.js vs from browser javascript
问题
I have translated the text as requested:
"对JavaScript还很陌生,正在努力理解库等概念。
我有一个启用了IAM身份验证的AWS API Gateway,想要使用JavaScript从浏览器访问它。为了实现这一目标,我需要两个外部库,分别是:@aws-sdk/signature-v4 和 @aws-sdk/sha256-js。
现在,在我的本地Node服务器上,我可以执行"npm install"以安装所需的包,并立即使用"require"语句来使用它,就像这样:
const express = require('express');
const app = express();
const port = 3000;
const axios = require('axios');
const SignatureV4 = require('@aws-sdk/signature-v4');
const sha256 = require('@aws-crypto/sha256-js');
API_URL
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
const apiUrl = new URL(API_URL);
const sigv4 = new SignatureV4.SignatureV4({
service: '#Service-Name#',
region: '#Region-Name#',
credentials: {
accessKeyId: AWS_ACCESS_KEY_ID,
secretAccessKey: AWS_SECRET_ACCESS_KEY
},
sha256: sha256.Sha256,
});
const handler = async () => {
const signed = await sigv4.sign({
method: 'GET',
hostname: apiUrl.host,
path: apiUrl.pathname,
protocol: apiUrl.protocol,
headers: {
'Content-Type': 'application/json',
host: apiUrl.hostname, // 必填项
},
});
try {
const { data } = await axios({
...signed,
url: API_URL, // 必填项
});
console.log('成功接收到数据:', data);
return data;
} catch (error) {
console.log('发生错误', error);
//throw error;
}
};
app.get('/', (req, res) => {
handler().then((result) => {
res.send(result);
});
});
app.listen(port, () => {
console.log(`我正在监听 http://localhost:${port}`);
});
现在,我似乎无法在浏览器端开始。显然,"require"在浏览器JavaScript上不起作用(至少对我来说抛出了错误),因此我开始探索使用ES6导入。为此,经过一些阅读,我发现可以使用一些CDN服务器来获取所需的包,但是aws-crypto的CDN链接已损坏(https://cdn.jsdelivr.net/npm/@aws-crypto/sha256-js@4.0.0/+esm 这个链接给我带来了一个导入错误:"无法读取null的属性(读取 '__exportStar')")
所以这让我想,我在本地Node文件夹中有所需的库,我是否可以以某种方式将它们打包成ES6模块并在我的网页中使用呢?但我不知道如何做到这一点,事实上,我甚至不知道我是否在正确的方向上。所以,任何帮助将不胜感激....谢谢。"
英文:
So new to JavaScript and trying to wrap my head around libraries and all.
I have an AWS API Gateway, with IAM authentication enabled. I want to hit it from my browser using JavaScript. In order to do that, I need 2 external libraries, namely: @aws-sdk/signature-v4 and @aws-sdk/sha256-js.
Now in my local node server, I can do an "npm install" for the required packages and straight away use it using "require" statements, like this:
// JavaScript source code
const express = require('express');
const app = express();
const port = 3000;
const axios = require('axios');
const SignatureV4 = require('@aws-sdk/signature-v4');
const sha256 = require('@aws-crypto/sha256-js');
API_URL
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
const apiUrl = new URL(API_URL);
const sigv4 = new SignatureV4.SignatureV4({
service: '#Service-Name#',
region: '#Region-Name#',
credentials: {
accessKeyId: AWS_ACCESS_KEY_ID,
secretAccessKey: AWS_SECRET_ACCESS_KEY
},
sha256: sha256.Sha256,
});
const handler = async () => {
const signed = await sigv4.sign({
method: 'GET',
hostname: apiUrl.host,
path: apiUrl.pathname,
protocol: apiUrl.protocol,
headers: {
'Content-Type': 'application/json',
host: apiUrl.hostname, // compulsory
},
});
try {
const { data } = await axios({
...signed,
url: API_URL, // compulsory
});
console.log('Successfully received data: ', data);
return data;
} catch (error) {
console.log('An error occurred',error);
//throw error;
}
};
app.get('/', (req, res) => {
handler().then((result) => {
res.send(result);
});
});
app.listen(port, () => {
console.log(`I am listening at http://localhost:${port}`);
});
Now, I can't seem to get started on the browser side. Apparently require won't work on browser javascript (at least it threw an error for me), so I started exploring using ES6 import. For that, after some reading, I figured to use some cdn servers to get my required packages, but the cdn for aws-crypto is broken ( https://cdn.jsdelivr.net/npm/@aws-crypto/sha256-js@4.0.0/+esm this gives me an import error: "Cannot read properties of null (reading '__exportStar')
" )
So it got me thinking, I have the required libraries in my local node folder, can't I somehow package them into ES6 modules and use it in my webpage..? But I don't know how to do that, in fact, I don't even know if I am on the right track. So any help would be appreciated....Thanks.
答案1
得分: 1
Finally got it working. So mentioning in case anyone faces a similar problem.
So, after reading around I found out about "Browserify". It basically bundled the different "require" packages recursively into a single JS file, which I later embedded into my HTML page with the script tag.
Also, I used @aws-amplify/core package for signing as it was a bit easier and it worked in my browser application.
So to summarize, I did the following steps:
-
Browserified the following script into a custom bundle:
const amp = require('@aws-amplify/core'); global.window.signer = amp.Signer;
-
Included the custom bundle in my web app (the bundle size is 1.5MB, will have to figure out how to minimize it if possible)
-
Now that the amplify's "signer" function was available in the global scope, I simply used it as mentioned here.
So, although I got it working this way, if anyone has a better idea, I would love to hear them out.
英文:
Finally got it working. So mentioning in case anyone faces a similar problem.
So, after reading around I found out about "Browserify". It basically bundled the different "require" packages recursively into a single JS file, which I later embeded into my html page with the script tag.
Also, I used @aws-amplify/core package for signing as it was a bit easier and it worked in my browser application.
So to summarize, I did the following steps:
-
Browserified the following script into a custom bundle:
const amp = require('@aws-amplify/core'); global.window.signer = amp.Signer;
-
Included the custom bundle in my web app (the bundle size is 1.5MB, will have to figure out to minimize it if possible)
-
Now that the amplify's "signer" function was available in the global scope, I simply used it as mentiond here
So, although I got it working this way, if anyone has a better idea, I would love to hear them out.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论