DEVDEV

AWS Lambda と React App で CSR付きリクエストを行う

作成日
2022-09-30
更新日
2022-10-11

前提知識

CSRとは、サーバ証明書を発行するための署名要求(Certificate Signing Request)のこと。

公開鍵の情報とディスティングイッシュネーム(組織名や組織の所在地などの情報)が含まれる。

構成

sequenceDiagram participant React App participant Lambda Edge(Proxy) React App->>Lambda Edge(Proxy): Request Lambda Edge(Proxy)->>Server: Request Server-->>Lambda Edge(Proxy): Response Lambda Edge(Proxy)-->>React App: Response

LambdaEdgeとCloudfrontFunctionsはEdgeFunctionなので、環境変数などを重くなる処理に制限が掛けられている。単純なリクエストヘッダーの変更以外で、認証したりする場合は、普通のLambdaの方が良いかも?

秘密鍵・公開鍵とCSRの作成

opensslを使用する。

bash
# 秘密鍵と公開鍵の作成 openssl genrsa 2048 > private_key.pem openssl rsa -in private_key.pem -pubout > public_key.pem # CSR発行 openssl req -new -key private_key.pem > development.csr openssl req -new -key private_key.pem > staging.csr openssl req -new -key private_key.pem > production.csr # 確認する openssl req -new -key public_key.pem > production.csr # 確認 openssl req -text -in development.csr openssl req -text -in staging.csr openssl req -text -in production.csr

AWS Proxyで証明書付きのリクエストを行う

Reactアプリ(クライアント)で直接、証明書付きのリクエストをしようとしても下記のエラーで実行できない。 (httpsモジュールはクライアントで実行できない)

Uncaught Error: Module "https" has been externalized for browser compatibility and cannot be accessed in client code.

js
import fs from 'fs' import https from 'https' import axios from 'axios' axios({ url: `https://localhost:8080/${route}`, method: "POST", data: formdata, httpsAgent: httpsAgent, })

基本の型

ts
var fs = require('fs'); var https = require('https'); var options = { key: fs.readFileSync('server-key.pem'), cert: fs.readFileSync('server-cert.pem'), ca: fs.readFileSync('apig-cert.pem'), requestCert: true, rejectUnauthorized: true }; https.createServer(options, function (req, res) { res.writeHead(200); res.end("hello world\n"); }).listen(443);
ts
const withCA: axios.AxiosRequestConfig = { httpsAgent: new https.Agent({ ca: [customRootCA], }) };

Step1: シンプルなLambdaをデプロイする

js
async function main(event) { console.log('domain 👉', process.env.DOMAIN) return { body: JSON.stringify({ message: 'SUCCESS 🎉' }), statusCode: 200, } } module.exports = { main }

Step2: 必要な情報を渡す

  • domainName
  • public.key
  • development.crt

参考

CSR

Lambda

Lambda環境変数

APIGateway

WAF

5分間で100回APIリクエストしたIPに対して、ブロックする。

ts
rules: [ { statement: { rateBasedStatement: { limit: 100, aggregateKeyType: 'IP', }, }, ],

メモ

  • NodejsFunctioncodeは、ファイル名まで指定する。
  • LambdaEdgeは、../srcのようにindex.jsがあるディレクトリを指定すれば良い。

aws_lambda_nodejs.NodejsFunction lambda.Functionと、Lambda@Edgeの違い

Related