0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LINEWORKS(WOFF)/LINE(LIFF)×AWSサーバーレスでのアーキテクチャをそれぞれ考えてみた

0
Posted at

はじめに

実務で、LINEWORKS/LINE×AWSサーバーレスでPoC開発をしました。
認証基盤を外部サービスに任せるため、そのサービスの設計思想がアーキテクチャに影響を与え、それぞれでアーキテクチャを組む必要がありました。ここでは、そのアーキテクチャをそれぞれ紹介しようと思います。

※本記事の構成・テーブル設計は、実案件の内容をそのまま記載したものではなく、説明用に簡略化・一般化したものです。

前提

ここでは、LINE WORKS/LINEアプリをAWSサーバーレス構成で開発する場合の認証設計について扱います。

主に、フロントエンドで取得したトークンを、バックエンド側でどのように検証し、API Gateway配下のLambdaを保護するかに焦点を当てます。

構成は以下を前提とします。

  • BtoB向けアプリの開発
  • フロントエンドはWOFF/LIFFアプリ
  • バックエンドはAWSサーバーレス構成
    • API Gateway
    • Lambda Authorizer
    • ロジック用Lambda
    • DynamoDB
  • 認証基盤そのものはLINE WORKS/LINE側に委任する

また、実案件ではWAFなどの防御層も検討しますが、本記事では認証設計とアーキテクチャの考え方を中心に整理します。

LINEWORKSのアーキテクチャ

image.png

各コンポーネントの責務

フロント

  • WOFF/LIFFアプリ初期化
  • ログイン
  • アクセストークン/IDトークンを取得してリクエスト

API Gateway

  • フロントからリクエストが来ると、Lambda Authorizerを発火
  • Lambda AuthorizerからTrueとユーザー情報が返ってくればロジックLambdaを発火

Lambda Authorizer

  • アクセストークン検証をリクエスト
  • ユーザー情報が返ってくればAPI GatewayにTrueとユーザー情報を返す

ロジックLambda

  • ビジネスロジックを実行

設計思想

Cognitoを使わず、外部サービスでの認証

自社でweb開発実績が少ないこと、開発者が自分1人であることから、認証周りのセキュリティ的責任を外部に委任したかった

アクセストークン/IDトークンでの検証

悪意ある第三者による外部からAWS環境へのアクセスを防ぎたかった

Lambda Authorizer

認証ロジックを共通化したかった

LINEWORKS/LINEの違い

LINEのアーキテクチャを紹介する前に、LINEWORKSとLINEの違いを説明します。

LINEWORKS

  • 無料版だと1テナント(団体)で30ユーザーまで
  • BtoBの設計思想(別テナントからアプリに入れない)

LINE

  • 無料版だとpushメッセージを月200通まで
  • BtoCの設計思想(LINEのアカウントさえあればアプリを利用可能)

LINEでBtoB向けのアプリ(特定のユーザーのみ使える)を開発する場合には、以下のようにアーキテクチャを組みました。

LINEのアーキテクチャ

image.png

DB設計

  • LINEユーザーと社員マスタの二つのエンティティをDBに持たせる
  • LINEユーザーと社員マスタの両方に、紐づけがされてるかの属性を持たせてる

1. LINEユーザーエンティティ

項目
PK USER#<lineUserId>
SK #METADATA

属性一覧

属性名 説明
status String フォロー状態 ACTIVE / BLOCKED / UNFOLLOWED
linkStatus String 社員 連携状態 LINKED / UNLINKED

2. 社員エンティティ

項目
PK EMP#<employeeId>
SK #METADATA

属性一覧

属性名 説明
linkStatus String LINE 連携状態 LINKED / UNLINKED
passwordHash String(bcryptでハッシュ化) パスワード $2b$...

大まかな流れ

  1. 公式アカウントを友達登録すると、LINEユーザーを登録(④)
1. LINEユーザーエンティティ
項目
PK USER#U0001
SK #METADATA
status ACTIVE
linkStatus UNLINKED
2. 社員エンティティ
項目
PK EMP#E001
SK #METADATA
linkStatus UNLINKED
passwordHash $2b$...
  1. アプリを開いて、社員マスタと紐づけがされてなかったら(⑨)、認証画面(IDとパスワード)を表示
  2. IDとパスワードを入力して送信し、正しければ両エンティティの紐づけの状態を更新する(⑩)
1. LINEユーザーエンティティ
項目
PK USER#U0001
SK #METADATA
status ACTIVE
linkStatus LINKED
2. 社員エンティティ
項目
PK EMP#E001
SK #METADATA
linkStatus LINKED
passwordHash $2b$...
lineUserId U0001

設計意図

ユーザーエンティティ LINEユーザー+社員マスタ vs LINEユーザーのみ

LINEユーザーは不特定多数の人が登録できるため、社員認証用として別エンティティを用意しました。

社員マスタでの認証 ID+パスワード vs ID+ワンタイムパスワード(Amazon SES)

メールだと、誤送信や再送制御などの運用負荷がかかるので、パスワードを採用しました。

社員エンティティにも紐づけ情報を保持

一度紐づけられてた社員証を使わせないようにしました。例えば、Aさんが社員Xとして紐づけられた後、Bさんが社員Xとして紐づけられてしまうのを防ぎます。

考慮した脆弱性の対策

「安全なWebアプリケーションの作り方」を読んで、以下の脆弱性を洗い出し、対策を立てました。

  • アカウントロック
    LINEアカウントごとにログイン試行回数を記録し、3回連続で失敗すると30分ロック。また、ログイン失敗率を計測し、それが急速に伸びてるときはプッシュ通知する。
  • エラーメッセージ
    ID、パスワード、アカウントロックのどれがエラーの原因かメッセージから特定できないようにする。

今後の課題

  • リクエストごとにLambda Authorizerを発火させないため、キャッシュ化する
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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?