この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
広島の吉川です。
早速ですが、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が返ってくることを確認できました。