LoginSignup
0
0

Reactで外部APIを使う際の備忘(+Lambda,APIGateway)

Posted at

背景

・Reactを学習し始め、Reactと外部APIを使った簡単なアウトプットをしたかった
・外部APIとのやり取りでセキュリティまわりで考えることがあったので備忘として残す

環境

Vite, React, Firebase, (+ Lambda, APIGateway)

どんなもの?

SpotifyAPIを使ってクリックするとプレイリストから曲を一つ取得して表示する
react.gif

(1) React, Firebaseのケース(情報が見えている)

FirebaseにReactページをデプロイしたかったが、SpotifyAPIとのやり取りに使うアクセストークンなどの情報が開発者ツールから見れる状態になっていた

.env
VITE_PLAYLIST_ID=xxxxxxxx
VITE_ACCESS_TOKEN=yyyyyyyy
xxx.jsx
// SpotifyAPIからデータを取ってくる処理
const spotify = () => {
  const apiUrl = `https://api.spotify.com/v1/playlists/${import.meta.env.VITE_PLAYLIST_ID}/tracks`;

  axios.get(apiUrl, { headers: { Authorization: `Bearer ${import.meta.env.VITE_ACCESS_TOKEN}` } })
};

これをFirebaseにデプロイして開発者ツールから見ると、実際の値が埋め込まれた状態になっていて見れてしまう

axios.get("https://api.spotify.com/v1/playlists/xxxxxxxx/tracks", { headers: { Authorization: "Bearer yyyyyyyy" } })

そのため上記のアクセストークンなどの情報を含む処理はサーバ側に持たせる必要があると認識し、候補としてLambdaが浮かんだ

(2) React, Firebase, Lambdaのケース(他の人からAPIを叩かれる可能性)

Lambdaに 関数URL という「APIGateway + Lambda」の構成を、Lambdaだけでもできるような機能があったのでそれを使ってみることにした(認証タイプはNONE)
スクリーンショット 2024-05-03 13.37.35.png

SpotifyAPIとのやり取りはLambdaに実装し、React側ではLambda関数URLにリクエストを送り、 Lambdaが得たデータを受け取る

index.mjs(Lambdaコード)
export const handler = async (event) => {
  const apiUrl = `https://api.spotify.com/v1/playlists/${process.env.PLAYLIST_ID}/tracks`;
  const spotifyData = await axios.get(apiUrl, {
    headers: {
      Authorization: `Bearer ${process.env.ACCESS_TOKEN}`,
    },
  });
  return spotifyData;
};
xxx.jsx
const spotify = async () => {
  const lambdaData = await axios.get({Lambda関数URLの値});
};

これで(1)であったアクセストークンなどの情報が見れてしまうという点は解消できたが、一点気になったことがあり、
Lambda関数URLの認証タイプをNONEにすると、誰からでもそのURLにアクセスできるということ。
Reactコードには上記のようにLambda関数URLを記述しているので、そうすると(1)と同じような感じで今度はLambda関数URLを知られAPIを叩くことができてしまう。
認証タイプにはNONEではなくIAM認証というのもあるが、今回の環境に対しては使えなさそうだったので、制御をかけれる他の機能としてAPIGatewayを使うことにした

(3) React, Firebase, Lambda, APIGatewayのケース(自分しかAPIを叩けないように制御)

APIGatewayのリソースポリシーを使ってIPアドレスでの制御をかけることができる

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
               "execute-api:/*"
            ],
            "Condition" : {
                "IpAddress": {
                    "aws:SourceIp": ["192.0.2.0/24", "198.51.100.0/24" ]
                }
            }
        }
    ]
}

React側はリクエストを送るURLをLambda関数URLからAPIGatewayのURLに変える

xxx.jsx
const spotify = async () => {
  const lambdaData = await axios.get({APIGatewayの値});
};

例えば許可するIPを自宅からのみにすれば、FirebaseにデプロイしてReactコードに書いてある上記APIGatewayのURLを知られても他の人からはAPIGatewayのURLにアクセスすることはできずAPIを叩かれることはなくなった

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0