VercelのOIDC認証付きバックエンドサーバーAWS EC2のセットアップ
概要
このガイドでは、Vercel OIDCを使用してAWS上にバックエンドサーバーをセットアップし、ローカルからEC2上のAPI接続テストを実施する手順を説明します。
前提条件
AWSアカウント
Vercelアカウント
Node.js(バージョン18.x以上推奨)
npm or yarn
EC2インスタンス(Ubuntu推奨)
EC2上にセットアップしたAPIはOIDC経由ではない状態で正常に動作
セットアップ手順
1. VercelアカウントでのOIDC設定を有効にする
Vercelダッシュボードからプロジェクトを開く
設定タブを選択します
セキュリティセクションで、OIDCフェデレーションによるバックエンドアクセスのセキュリティを有効にする
参考リンク:https://vercel.com/docs/security/secure-backend-access/oidc
2. AWS IAMロールの設定
AWSコンソールでIAMに移動
新しいロールを作成(例:vercel-oidc-test-240925)
信頼関係を以下のように設定:
AWSコンソールに移動する
IAMに移動し、次にアイデンティティプロバイダに移動します
プロバイダーの追加を選択
プロバイダータイプからOpenID Connectを選択します
プロバイダーURLフィールドhttps://oidc.vercel.comに入力します
オーディエンスhttps://vercel.com/[TEAM_SLUG]フィールドに、VercelチームのURLのパスを置き換えて入力します。[TEAM_SLUG]
プロバイダーの追加を選択
必要な権限ポリシーをアタッチ(例:AdministratorAccess)
ロールを作成したら、ロールの ARNをコピーし、キー名を使用して Vercel プロジェクトで"AWS_ROLE_ARN"環境変数として宣言します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::[your account number]:oidc-provider/oidc.vercel.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.vercel.com:aud": "https://vercel.com/test-46f30ef0"
},
"StringLike": {
"oidc.vercel.com:sub": [
"owner:test-46f30ef0:project:*:environment:preview",
"owner:test-46f30ef0:project:*:environment:production",
"owner:test-46f30ef0:project:*:environment:development"
]
}
}
}
]
}
AWS_ROLE_ARN=arn:aws:iam::accountid:user/username
2. EC2インスタンスのセットアップ
EC2インスタンスを起動(Ubuntu推奨)
SSHでインスタンスに接続
3. 環境変数の設定
EC2インスタンスで以下のコマンドを実行:
echo 'export AWS_REGION="ap-south-1"' >> ~/.bashrc
echo 'export AWS_ROLE_ARN="arn:aws:iam::[account number]:role/vercel-oidc-test-240925"' >> ~/.bashrc
echo 'export PORT="3000"' >> ~/.bashrc
echo 'export VERCEL_OIDC_TOKEN="teamtoken"' >> ~/.bashrc
echo 'export VERCEL_PROJECT_ID="projectid"' >> ~/.bashrc
source ~/.bashrc
4. Node.jsとnpmのインストール
sudo apt update
sudo apt install nodejs npm
5. プロジェクトのセットアップ
プロジェクトディレクトリを作成し、移動
6. サーバーコードの作成
`server.js`ファイルを作成し、必要なコードを記述。以下は一例。
const express = require('express');
const mongoose = require('mongoose');
const { PORT, MONGODB_URI } = require('./src/config');
const cors = require('cors');
const app = express();
const { STSClient, AssumeRoleWithWebIdentityCommand } = require("@aws-sdk/client-sts");
// CORS設定
app.use(cors({
origin: [
'https://xxxxx.vercel.app',
],
credentials: true
}));
app.use(express.json());
// デバッグミドルウェア
app.use((req, res, next) => {
console.log('Received request with headers:', req.headers);
console.log('Authorization header:', req.headers.authorization);
next();
});
// 認証ミドルウェア
async function validateVercelOIDCToken(req, res, next) {
const authHeader = req.headers['authorization'];
if (!authHeader) {
return res.status(401).json({ error: "No authorization header provided" });
}
const token = authHeader.split(' ')[1];
if (!token) {
return res.status(401).json({ error: "No token provided" });
}
try {
console.log('Attempting to assume role with token');
console.log('AWS_REGION:', process.env.AWS_REGION);
console.log('AWS_ROLE_ARN:', process.env.AWS_ROLE_ARN);
const sts = new STSClient({ region: process.env.AWS_REGION });
const command = new AssumeRoleWithWebIdentityCommand({
RoleArn: process.env.AWS_ROLE_ARN,
RoleSessionName: 'VercelSession',
WebIdentityToken: token
});
const result = await sts.send(command);
console.log('Successfully assumed role:', result);
next();
} catch (error) {
console.error("Error assuming role:", error);
res.status(401).json({ error: "Invalid Vercel OIDC token", details: error.message });
}
}
mongoose.connect(MONGODB_URI, {})
.then(() => console.log('Connected to MongoDB'))
.catch(err => {
console.error('MongoDB connection error:', err);
process.exit(1);
});
// activeAPIの使用
app.use('/api/active', validateVercelOIDCToken, activeRoutes);
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Something went wrong!' });
});
app.listen(PORT, '0.0.0.0', () => {
console.log(`Server is running on port ${PORT}`);
});
7. Vercel CLIでローカルへVERCEL_OIDC_TOKENをダウンロード
ダウンロードされた.env.localへ対象となるその他の環境変数が書き込まれる。環境変数としてセット。
npm i -g vercel
vercel env pull
vercel link
echo 'export VERCEL_OIDC_TOKEN="XXXXXX"' >> ~/.bashrc
source ~/.bashrc
8.ローカルでEC2上のAPIとの接続テスト
以下はテストスクリプト例
if [ -z "$VERCEL_OIDC_TOKEN" ]; then
echo "Error: VERCEL_OIDC_TOKEN is not set."
exit 1
fi
echo "Sending request with VERCEL_OIDC_TOKEN..."
curl -v -H 'Authorization: Bearer '"$VERCEL_OIDC_TOKEN"'' \
"https://XXXX.com/api/active/check/0x1234567890123456789012345678901234567890"
echo -e "\n\nSending request without token for comparison..."
curl -v "https://XXXX.com/api/active/check/0x1234567890123456789012345678901234567890"