[CDK] AppSyncのOIDCプロバイダーにLINEを設定したい
広島の吉川です。
早速ですが、AWS AppSync APIにLIFFアプリ/LINEミニアプリの認証を設定する方法を紹介します。
環境
- node 16.13.0
- typescript 3.9.7
- aws-cdk 2.20.0
- aws-cdk-lib 2.20.0
- @aws-cdk/aws-appsync-alpha 2.20.0
- constructs 10.0.115
LINE ChannelとLIFF Applicationを作成
LINE Developersより、LINEプロバイダ選択→「Create a new Channel」押下→「LINE Login」押下でChannel新規作成画面を開き、
- Channel type: 「LINE Login」
- Provider: 任意
- Region: 「Japan」
- Company or owner's country or region: 「Japan」
- Channel icon: 任意
- Channel description: 任意
- App types: 「Web app」+「Mobile app」
- Email address: 任意
- Privacy policy URL: 空欄
- Terms of use URL: 空欄
としてChannelを作成します。
続いてChannelの中にLIFFを作成します。「LIFF」タブを選択→「Add」を押下し、
- LIFF app name: 任意
- Size: Full
- Endpoint URL:
https://localhost:5000
- Scopes: 「openid」
- Bot link feature
としてLIFF Applicationを作成します。Scopesが重要となっており、今回はOIDCを使うのでopenidにチェックを入れておいてください。
上記作成後、
- LINE Login Channel ID
- LIFF ID
をそれぞれ控えておきます。
GraphQL Schemaファイル
type User { lineUserId: String! } type Query { findUser: User! }
DataSourceとするLambda関数コード
「IDトークンから得られたLINEユーザIDを返す」というシンプルなLambda関数を用意します。
// lambda-handler/find-user-handler.ts import { AppSyncIdentityOIDC, AppSyncResolverEvent } from 'aws-lambda' export const handler = async (event: AppSyncResolverEvent<{}, {}>) => { console.log(JSON.stringify({ event })) const lineUserId = (event.identity as AppSyncIdentityOIDC).sub return { lineUserId, } }
ちなみに、 event
引数をdumpした中身は下のようになります。機密情報は大文字スネークケースの文字列などでマスクしています。
{ "event": { "arguments": {}, "identity": { "claims": { "sub": "LINE_USER_ID", "aud": "LINE_LOGIN_CHANNEL_ID", "amr": ["linesso"], "iss": "https://access.line.me", "exp": 1234567891, "iat": 1234567891 }, "issuer": "https://access.line.me", "sub": "LINE_USER_ID" }, "以下省略": "..." } }
CDKコード
- authorizationType: OIDC
- oidcProvider:
'https://access.line.me'
- clientId: LINE Login Channel ID
を設定することがポイントとなります。
// lib/appsync-stack.ts import * as appsync from '@aws-cdk/aws-appsync-alpha' import * as lambdaNodejs from 'aws-cdk-lib/aws-lambda-nodejs' import * as cdk from 'aws-cdk-lib' import { Construct } from 'constructs' export class AppSyncStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props) // AppSyncAPIを作成 const api = new appsync.GraphqlApi(this, 'myAppsyncApi', { name: 'myAppsyncApi', schema: appsync.Schema.fromAsset('./schema.graphql'), authorizationConfig: { defaultAuthorization: { authorizationType: appsync.AuthorizationType.OIDC, openIdConnectConfig: { oidcProvider: 'https://access.line.me', clientId: 'LINE_LOGIN_CHANNEL_ID', // LINE Login Channel ID }, }, }, xrayEnabled: true, }) // Lambda関数を作成 const findUserFn = new lambdaNodejs.NodejsFunction(this, 'findUserFn', { entry: 'lambda-handler/find-user-handler.ts', }) // Lambda関数をDataSourceとしてAppSyncAPIと紐付ける const findUserDs = api.addLambdaDataSource('findUserDs', findUserFn) // schema.graphqlで定義した中のどの操作とマッピングするかを指定 findUserDs.createResolver({ typeName: 'Query', fieldName: 'findUser', }) } }
動作確認
LIFFアプリを立ち上げてIDトークンを取得
動作確認にあたって、検証用のLINE IDトークンを取得する必要があります。こちらを確認するには、
- 確認用LIFFアプリを1から自作し、getIDTokenメソッドを呼び出して返り値を確認する
- liff-playgroundを
git clone
してデプロイして確認する - line-liff-v2-starterを
git clone
してデプロイして確認する
などからいずれかの方法を採ると良いと思います。
IDトークンを取得できたら、AWSマネジメントコンソールでAppSyncを開きます。左メニューで「クエリ」を選択し、「Authorization Token:」の入力欄にトークンを貼り付けてクエリを実行します。
すると、このようにLINEユーザIDが返ってくることを確認できました。