🛤️
Severless Framework + TypeScriptでAppSyncのLambda認証をする
Serverless frameworkのAppSyncプラグインでもlambda認証が設定できるようになっているので動作を確認してみました。
基本的な設定は以前の記事と大体一緒です。
作成元のソースはServerless Framework + TypeScriptでAppSync環境構築するの記事を参照してください
結論
- AppSyncのプラグインでAWS上に正しくデプロイはできる
- ただし、
serverless offline
はまだ動作しないので、ローカルで開発するにはちょっとしんどい。
実装
ソースはGithubにあるので、参考にどうぞ
lambda
- srcはlambda認証の時に書いたものをそのまま利用します
https://zenn.dev/merutin/articles/02960a57bb8947
src/handler.ts
export const sampleAuth = async (event: any) => {
console.log(`event >`, JSON.stringify(event, null, 2));
const {
authorizationToken,
requestContext: { apiId, accountId },
} = event;
const response = {
// ここがfalseの場合は認証失敗になる
isAuthorized: true,
// 後続処理に渡せる情報。vtlやリゾルバーに渡す値として利用できる
// ここで権限チェック系の共通処理の結果を渡してあげるとよさそう
resolverContext: {
userid: "test-user-id",
info: "contextual information A",
more_info: "contextual information B",
},
// 拒否するfieldを選択できる
deniedFields: [
// 特定のtypeのフィールドのみを禁止したい場合
`arn:aws:appsync:${process.env.AWS_REGION}:${accountId}:apis/${apiId}/types/Post/fields/comments`,
// 特定のmutationを禁止したい場合
`Mutation.createEvent`,
],
ttlOverride: 10,
};
console.log(`response >`, JSON.stringify(response, null, 2));
return response;
};
graphql
- sampleクエリの認証タイプだけ変更します
- 前の時に追加してなかったのに動いてたのなんでだろうか。。
graphql/schema.graphql
type Query {
- sample: String!
+ sample: String! @aws_lambda
}
serverless.ts
lambda認証に変更するためにserverless.tsを修正します。
- AppSyncの認証方法の変更
- sampleAuthの関数の定義
import type { AWS } from "@serverless/typescript";
const serverlessConfiguration: AWS = {
service: "serverless-appsync-lambda-test",
frameworkVersion: "2",
custom: {
webpack: {
webpackConfig: "./webpack.config.js",
includeModules: true,
},
appSync: {
name: "appsync-sample-${opt:stage}",
- authenticationType: "API_KEY",
+ authenticationType: "AWS_LAMBDA",
schema: "./graphql/schema.graphql",
- apiKeys: [
- {
- name: "test-api-key",
- description: "AppSync test",
- expiresAfter: "30d",
- },
- ],
+ lambdaAuthorizerConfig: {
+ functionName: "sampleAuth",
+ },
defaultMappingTemplates: {
request: false,
response: false,
},
mappingTemplates: [
// queryとdataSourceを結びつける部分
{
dataSource: "sample",
type: "Query",
field: "sample",
},
],
dataSources: [
// lambdaをdataSourceに設定する部分。この設定をすることでAppSyncからlambdaを呼び出せる
{
type: "AWS_LAMBDA",
name: "sample",
config: {
functionName: "sample",
},
},
],
},
"appsync-simulator": {
location: ".webpack/service",
apiKey: "da2-fakeApiId123456",
watch: false,
},
},
plugins: [
"serverless-webpack",
"serverless-appsync-simulator",
"serverless-appsync-plugin",
"serverless-offline",
],
provider: {
name: "aws",
runtime: "nodejs14.x",
stage: '${opt:stage, "local"}',
region: "ap-northeast-1",
environment: {
AWS_NODEJS_CONNECTION_REUSE_ENABLED: "1",
},
lambdaHashingVersion: "20201221",
},
functions: {
sample: {
handler: "src/handler.sample",
},
+ sampleAuth: {
+ handler: "src/handler.sampleAuth",
+ },
},
};
module.exports = serverlessConfiguration;
実行
開発環境の起動
まずはofflineで起動して、http://localhost:20002にアクセスします。
npx serverless offline start --stage local
何も表示されません。。
詳細を調べていきます。
offlineの起動では、serverless-appsync-simulatorが動いています。
serverless-appsync-simulatorは中身を見てみると、ほぼ、amplify-appsync-simulatorを実行しているだけになります。
なので、原因は以下のどちらかになりそうです。
- serverless-appsync-simulatorの利用しているamplify-appsync-simulatorが古い
- amplify-appsync-simulatorが対応していない
amplify-appsync-simulatorを見ていたら以下のissueがありました。
まだ対応されていないようです。残念ですが、対応されるのを待ちましょう。
AWS上での起動
AWSにデプロイして動作を確認してみます。
npx serverless deploy --stage dev
AppSyncのコンソールから実行してみました。
正しくデプロイできていることがわかります。
念のため、CloudWatch logの情報も見てみます。
ちゃんと実行されていることがわかります(※一部情報はxxxでマスクしています)。
2021-11-08T03:31:14.762Z 81eb0e5f-9440-41ca-b9a3-b6e84142b1f0 INFO event > {
"authorizationToken": "xxx",
"requestContext": {
"apiId": "xxx",
"accountId": "xxx",
"requestId": "xxx-9fab-42b3-b89e-929f4420c906",
"queryString": "query MyQuery {\n sample\n}\n",
"operationName": "MyQuery",
"variables": {}
}
}
Discussion