こんにちは!開発エンジニアのクリスです。

ノーコードでサクッとアプリが作れる AppSheet、本当に便利ですよね!

タスク管理や案件一覧など、いろんなシステムをAppSheetをフロントエンドとして利用しているケースも多いと思います。

でも、作ったアプリを複数ユーザーで利用し始めると、こんな悩みが出てきませんか?

「このタスク一覧、Aさんには見せたいけど、Bさんには見せたくない…」

「自分の所属するプロジェクトの課題だけ表示したい…」

そんな時に大活躍するのが、今回ご紹介する「Security Filter」機能です!

これを使えば、ログインしているユーザーに応じて表示するデータを動的に制御できるんです。

今回は、具体的な「プロジェクト管理」のシナリオを例に、Security Filterの設定方法を分かりやすく解説していきます!

プロジェクト管理を例として説明

背景 / 前提条件

まずは今回のシナリオです。

  • あるグループ(部署やチーム)が、複数のプロジェクトを管理しています。
  • 各プロジェクトには、複数の課題(タスク)が紐づいています。
  • ユーザーは、自分が所属しているグループがアクセスを許可されているプロジェクトの課題しか閲覧・操作できないようにしたい。

これを実現するために、まずはデータベース(今回はGoogleスプレッドシートやCloud SQLを想定)のテーブル構成を考えてみましょう。

テーブル構成

検証のために、最小限の構成でテーブル(シート)を用意しました。

Groupテーブル
GroupID (PK), GroupName

Usersテーブル
UserEmail (PK), UserName, Role

Issuesテーブル
IssueID (PK), _fk_ProjectID (FK), UpdatedDateTime, assigneeName, Title, Status, DueDate, IssueLink, IssueType, CreatedDateTime, CreatedUserName, IsChildIssue, estimatedHours, actualHours, Category, updatedUser, Milestone

Projectsテーブル
ProjectID (PK), ProjectName

UserGroupMembershipテーブル(ユーザーとグループの中間テーブル)
MembershipID (PK), _fk_UserEmail (FK), _fk_GroupID (FK)

ProjectGroupAccessテーブル(プロジェクトとグループの中間テーブル)
AccessID (PK), _fk_ProjectID (FK), _fk_GroupID (FK)

 

関係図

これらのテーブル間の関係を図にすると、こんな感じです。

 

Security Filter 設定方法

お待たせしました!ここからが本題のAppSheetでの設定手順です。

1. DataをAppSheetに連携する

 

まずは、作成したテーブル(シート)をAppSheetの [Data] セクションから連携します。

Tips: Cloud SQLを利用する場合

AppSheetからCloud SQLなどのデータベースへ接続する場合、AppSheetが使用するIPアドレスからのアクセスを許可してあげる必要があります。

許可すべきIPリストは 公式ドキュメント に記載されています。

(このリスト、更新頻度は高くないようですが、Google内部の変更で変わる可能性もあるので、メンテナンスが必要です)

2. 外部キー(FK)列のTypeを “Ref” に設定する

AppSheetがテーブル間のリレーションを理解できるように、外部キー(fkから始まる列など)のTypeを設定します。

  • Issuesテーブルの _fk_ProjectID
  • UserGroupMembershipテーブルの _fk_UserEmail_fk_GroupID
  • ProjectGroupAccessテーブルの _fk_ProjectID_fk_GroupID

これらの列のTypeを [Ref] に変更し、[Source table] で参照先のテーブル(例: _fk_ProjectID なら Projectsテーブル)を正しく選択します。

Tips: “Is a part of?” の設定

Ref設定にある Is a part of? というオプション。これはデータベースでいう ON DELETE CASCADE(親レコードを削除したら子レコードも連動して削除する)と同じような意味を持ちます。

データソースがスプレッドシートの場合はAppSheet側で設定が必要ですが、Cloud SQL側で既にリレーショナルなスキーマ設定(カスケード削除など)がされていれば、AppSheet側で特に意識する必要はありません。

3. “自分が所属するグループ” のスライス(Slice)を作成する

次に、[Data] > [Slices] で新しいスライスを作成します。

ここでは「MyProjects」という名前のスライスを、ProjectGroupAccessテーブルを元に作成します。

このスライスの役割は、「今ログインしているユーザーが所属するグループがアクセスできるプロジェクト」の一覧(の元データ)を作ることです。

[Row filter condition] に以下の式を設定します。

IN( [_fk_GroupID], SELECT( UserGroupMembership[_fk_GroupID], [_fk_UserEmail] = USEREMAIL() ) ) 

式の解説:

  1. USEREMAIL() で、今ログインしているユーザーのEmailを取得します。
  2. SELECT(UserGroupMembership[_fk_GroupID], [_fk_UserEmail] = USEREMAIL()):
    UserGroupMembershipテーブルから、ログイン中ユーザーのレコード(_fk_UserEmailが一致)を探し、そのユーザーが所属する _fk_GroupID のリストを抽出します。
  3. IN([_fk_GroupID], ... )ProjectGroupAccessテーブルの _fk_GroupID が、ステップ2で抽出した「自分が所属するグループIDリスト」に含まれている(IN)レコードだけをフィルタリングします。

これで、MyProjectsスライスには、ログインユーザーが権限を持つプロジェクトとグループの紐付け情報だけが含まれるようになります。

4. “Issues” テーブルに Security Filter を設定する

いよいよ大詰めです!

Issuesテーブル(課題一覧)の設定を開き、[Security] > [Security filter] に以下の式を設定します。

IN([_fk_ProjectID], MyProjects[_fk_ProjectID]) 

式の解説:

これはシンプルですね!

  • MyProjects[_fk_ProjectID]:ステップ3で作成したスライス MyProjects に含まれる _fk_ProjectID のリスト(つまり、ログインユーザーがアクセス権を持つプロジェクトIDのリスト)を取得します。
  • IN([_fk_ProjectID], ... )Issuesテーブルの _fk_ProjectID が、先ほどの「アクセス権を持つプロジェクトIDリスト」に含まれている(IN)課題(Issue)だけを表示するようにフィルタリングします。

これで設定は完了です!

アプリを同期(Sync)して、別のユーザーでログイン(Preview as)してみてください。そのユーザーが所属するグループがアクセスできるプロジェクトの課題だけが表示されるようになっているはずです。

その他注意事項

最後に、AppSheetを運用する上で知っておきたい注意点をいくつか。

  • データ連携はリアルタイムではない
    • AppSheetは、基本的に「同期(Sync)」ボタンを押したタイミングでデータベース(スプシやCloud SQL)とデータをやり取りします。ユーザーがアプリ上でデータを変更した場合、まずAppSheet内部のデータベースに保存され、その後の同期で実際のデータベースに反映される、という流れを理解しておくことが重要です。
  • データ型(Type)はAppSheet側で正しく設定する
    • データソースがスプレッドシートでもSQLデータベースでも、AppSheetは一度テーブルを連携した後、各列のType(Text, Number, Email, Refなど)をAppSheet側で正しく設定する必要があります。AppSheetが「これは数値のはず」「これは日付のはず」と判断するためのスキーマ設定は、データソース側とは別にAppSheet側でも必要になります。
  • データの整合性
    • 上記の理由から、データの整合性(親子関係の担保など)は、AppSheet側(Ref設定やValid_ifなど)と、後ろのデータベース側(スキーマ設定)の両方で担保することを意識する必要があります。

さいごに

今回は、AppSheetの「Security Filter」機能を使って、ユーザーごとに表示データを制御する方法を解説しました。

スライスと USEREMAIL() 関数を組み合わせることで、かなり柔軟な閲覧権限コントロールが可能になります。

「見せたくない情報」をしっかり隠すことは、アプリを安全に運用するための第一歩です。ぜひこのテクニックを活用して、セキュアで使いやすいAppSheetアプリを構築してみてください!