アプリの配布 (OAuth)
新しく作られた Slack アプリは、はじめは開発用ワークスペース(Development Workspace)にだけインストールすることができます。OAuth Redirect URL を設定して App Distribution を有効にすると、そのアプリは他のどのワークスペースにもインストールできるようになります。
Slack アプリの設定
アプリの配布を有効にするには Slack アプリ管理画面にアクセスし、開発中のアプリを選択、左ペインの Settings > Manage Distribution へ遷移します。ページの説明に従って設定を行います。
Redirect URL については Bolt for Java では https://{あなたのドメイン}/slack/oauth/callback
のような URL で応答します。この URL を変更する方法などはこのページのあとのセクションの一覧を参照してください。
Bolt for Java は、バー ジョン 1.4.0 から自動的に OrG 全体へのインストール機能に対応しています。OrG 全体へのインストールは、Slack アプリ管理画面の Org Level Apps にある設定から有効にしてください。
Bolt アプリがやること
Bolt アプリが OAuth フローをハンドルするためにやらなければならないことは以下の通りです。
- ユーザーを Slack の Authorize エンドポイントに必要なパラメーターとともに誘導する OAuth フロー開始のエンドポイントを提供する
state
パラメーターの値を生成して、後ほどその検証を行うclient_id
,scope
,user_scope
(v2 のみ),state
パラメーターを URL に付加する
- Slack からリダイレクトされてきたユーザーリクエストを処理するエンドポイントを提供する
state
パラメーターが正当かを検証する- oauth.v2.access (レガシーアプリの場合は oauth.access) API メソッドを呼び出してトークンを発行し、それを保存することでインストールを完了させる
- インストールを実行したユーザーを誘導する完了・エラーページを用意する
- これらの URL は通常別のどこかであることが多いが、Bolt アプリがそれをサーブすることも可能
コード例
以下は OAuth フローの実装例です。OAuth フローのハンドリング機能は多くのカスタムアプリには必要ないので、Bolt のデフォルトの状態ではこの機能は無効化されています。App インスタンスは、それを有効にする場合は asOAuthApp(true)
を明に呼び出す必要があります。
import com.slack.api.bolt.App;
import com.slack.api.bolt.jetty.SlackAppServer;
import java.util.HashMap;
import java.util.Map;
import static java.util.Map.entry;
// Slack API からのペイロードリクエストを処理する App
// 環境変数 SLACK_SIGNING_SECRET が存在する前提
App apiApp = new App();
apiApp.command("/hi", (req, ctx) -> {
return ctx.ack("Hi there!");
});
// OAuth フローを処理する App
// 以下の環境変数が設定されている前提:
// SLACK_CLIENT_ID, SLACK_CLIENT_SECRET, SLACK_REDIRECT_URI, SLACK_SCOPES,
// SLACK_INSTALL_PATH, SLACK_REDIRECT_URI_PATH
// SLACK_OAUTH_COMPLETION_URL, SLACK_OAUTH_CANCELLATION_URL
App oauthApp = new App().asOAuthApp(true);
// これら二つの App をルーとパスの指定とともにマウント
SlackAppServer server = new SlackAppServer(new HashMap<>(Map.ofEntries(
entry("/slack/events", apiApp), // POST /slack/events (Slack API からのリクエストのみ)
entry("/slack/oauth", oauthApp) // GET /slack/oauth/start, /slack/oauth/callback (ユーザーがブラウザーでアクセス)
)));
server.start(); // http://localhost:3000
技術的には、一つの App を Slack API からのリクエストと OAuth フローにおけるユーザーインタラクションの両方に使うことは可能です。しかし、ほとんどのアプリは OAuth フローのためのルートパスは別のものにすると想定されるので、上の例はそのようになっています。
配布可能な Slack アプリのための設定
以下は配布可能なアプリのための設定項目の一覧です。もしこれら以外の環境変数名や、別の読み込みの仕組みを使いたい場合は、 自前で AppConfig を初期化する実装を行ってください。
環境変数名 | 説明 (値を見つけられる場所) |
---|---|
SLACK_SIGNING_SECRET | Signing Secret: リクエスト検証のための秘密キー (Settings > Basic Information > App Credentials) |
SLACK_CLIENT_ID | OAuth 2.0 Client ID (Settings > Basic Information > App Credentials) |
SLACK_CLIENT_SECRET | OAuth 2.0 Client Secret (Settings > Basic Information > App Credentials) |
SLACK_REDIRECT_URI | OAUth 2.0 Redirect URI (Features > OAuth & Permissions > Redirect URLs) |
SLACK_SCOPES | カンマ区切りの bot scope リスト: scope パラメーターは https://slack.com/oauth/authorize や https://slack.com/oauth/v2/authorize にクエリパラメーターとして付加されます (Settings > Manage Distribution > Sharable URL から scope の値を取得) |
SLACK_USER_SCOPES (v2 のみ) | カンマ区切りの user scope リスト: user_scope パラメーターは https://slack.com/oauth/v2/authorize にクエリパラメーターとして付加されます (Settings > Manage Distribution > Sharable URL, から user_scope の値を取得) |
SLACK_INSTALL_PATH | OAuth フロ ーの開始点: このエンドポイントはユーザーを client_id , scope , user_scope (v2 のみ), state とともに Slack の Authorize エンドポイントにリダイレクトします。推奨するパスは /slack/oauth/start ですが、どのようなパスでも構いません。 |
SLACK_REDIRECT_URI_PATH | OAuth Redirect URI: このエンドポイントは Slack の OAuth 許可確認画面からの callback リクエストを処理します。このパスは SLACK_REDIRECT_URI の値と整合している必要があります。推奨のパスは /slack/oauth/callback ですが、どのようなパスでも構いません。 |
SLACK_OAUTH_COMPLETION_URL | Installation Completion URL: インストール完了画面の URL を指定します。どんな URL でも構いません。 |
SLACK_OAUTH_CANCELLATION_URL | Installation Cancellation/Error URL: キャンセルやエラーが発生したときの遷移先 URL を指定します。どんな URL でも構いません。 |
ストレージサービスの選択
デフォルトでは OAuth フローをサポートする Bolt アプリは、ローカルファイルシステムを state パラメーターやトークンの保存先に使用します。Bolt はそれ以外にも以下の選択肢に標準で対応しています。
- ローカルファイルシステム
- Amazon S3
- リレーショナルデータベース (via JDBC) - 近日対応予定
もし使いたいデータストアがサポートされていない場合でも com.slack.api.bolt.service.InstallationService と com.slack.api.bolt.service.OAuthStateService の interface を実装すれば利用することができます。
以下は Amazon S3 をバックエンドとして使用したサンプル例です。
import com.slack.api.bolt.App;
import com.slack.api.bolt.jetty.SlackAppServer;
import com.slack.api.bolt.service.InstallationService;
import com.slack.api.bolt.service.OAuthStateService;
import com.slack.api.bolt.service.builtin.AmazonS3InstallationService;
import com.slack.api.bolt.service.builtin.AmazonS3OAuthStateService;
import java.util.HashMap;
import java.util.Map;
import static java.util.Map.entry;
// 標準的な AWS の環境変数が設定済であることが前提
// export AWS_REGION=us-east-1
// export AWS_ACCESS_KEY_ID=AAAA*************
// export AWS_SECRET_ACCESS_KEY=4o7***********************
// この bucket のセキュリティポリシーには十二分にご注意ください
String awsS3BucketName = "YOUR_OWN_BUCKET_NAME_HERE";
InstallationService installationService = new AmazonS3InstallationService(awsS3BucketName);
// 全てのインストール結果を別のレコードとして保存したい場合は true をセット
installationService.setHistoricalDataEnabled(true);
// apiApp はトークンの取得のために InstallationService だけを利用します
App apiApp = new App();
apiApp.command("/hi", (req, ctx) -> {
return ctx.ack("Hi there!");
});
apiApp.service(installationService);
// 言うまでもなく oauthApp は InstallationService を利用します
// それに加えて state パラメーターの生成/参照/廃棄のために OAuthStateService を利用します
App oauthApp = new App().asOAuthApp(true);
oauthApp.service(installationService);
// state パラメーターの値を Amazon S3 ストレージに保存
OAuthStateService stateService = new AmazonS3OAuthStateService(awsS3BucketName);
// このサービスは OAuth フローに対応する App のみに必要
oauthApp.service(stateService);
// ルーとパスとともに二つの App をマウント
SlackAppServer server = new SlackAppServer(new HashMap<>(Map.ofEntries(
entry("/slack/events", apiApp), // POST /slack/events (Slack API からのリクエストのみ)
entry("/slack/oauth", oauthApp) // GET /slack/oauth/start, /slack/oauth/callback (ユーザーがブラウザーでアクセス)
)));
server.start(); // http://localhost:3000
もしトークンローテーションを有効にしたいという場合は、あなたの InstallationService
がトークンローテーション互換である必要があります。詳細は v1.9.0 のリリースノート(英語)を参考にしてください。
Granular Permission Apps と Classic Apps
Slack アプリインストールには、二つの OAuth フローがあります。V2(ちょっと紛らわしいですが OAuth のバージョンではなく Slack OAuth フローのバージョンです)の OAuth フローでの Slack アプリは(特にボットユーザーの権限に関して)旧来に比べてより詳細な必要最小限の権限だけをリクエストできるようになりました。二つのやり方の違いは v2
を Authorization URL やトークンを発行する API メソッドの URL に含んでいることと、API レスポンスのデータ構造に若干の変更が加わっていることです。
V2 OAuth 2.0 フロー (デフォルト)
|-|-|
|Authorization URL|https://slack.com/oauth/v2/authorize
|
|トークン発行の API メソッド|oauth.v2.access
(レスポンス)|