|
| 1 | +--- |
| 2 | +title: OAuth を使った認証 |
| 3 | +lang: ja-jp |
| 4 | +slug: authenticating-oauth |
| 5 | +order: 15 |
| 6 | +--- |
| 7 | + |
| 8 | +<div class="section-content"> |
| 9 | + |
| 10 | +Slack アプリを複数のワークスペースにインストールできるようにするためには、OAuth フローを実装した上で、アクセストークンなどのインストールに関する情報をセキュアな方法で保存する必要があります。アプリを初期化する際に `client_id`、`client_secret`、`scopes`、`installation_store`、`state_store` を指定することで、OAuth のエンドポイントのルート情報や stateパラメーターの検証をBolt for Python にハンドリングさせることができます。カスタムのアダプターを実装する場合は、SDK が提供する組み込みの[OAuth ライブラリ](https://slack.dev/python-slack-sdk/oauth/)を利用するのが便利です。これは Slack が開発したモジュールで、Bolt for Python 内部でも利用しています。 |
| 11 | + |
| 12 | +Bolt for Python によって `slack/oauth_redirect` という**リダイレクト URL** が生成されます。Slack はアプリのインストールフローを完了させたユーザーをこの URL にリダイレクトします。この**リダイレクト URL** は、アプリの設定の「**OAuth and Permissions**」であらかじめ追加しておく必要があります。この URL は、後ほど説明するように `OAuthSettings` というコンストラクタの引数で指定することもできます。 |
| 13 | + |
| 14 | +Bolt for Python は `slack/install` というルートも生成します。これはアプリを直接インストールするための「**Add to Slack**」ボタンを表示するために使われます。すでにワークスペースへのアプリのインストールが済んでいる場合に追加で各ユーザーのユーザートークンなどの情報を取得する場合や、カスタムのインストール用の URL を動的に生成したい場合などは、`oauth_settings` の `authorize_url_generator` でカスタムの URL ジェネレーターを指定することができます。 |
| 15 | + |
| 16 | +バージョン 1.1.0 以降の Bolt for Python では、[OrG 全体へのインストール](https://api.slack.com/enterprise/apps)がデフォルトでサポートされています。OrG 全体へのインストールは、アプリの設定の「**Org Level Apps**」で有効化できます。 |
| 17 | + |
| 18 | +Slack での OAuth を使ったインストールフローについて詳しくは、[API ドキュメントを参照してください](https://api.slack.com/authentication/oauth-v2)。 |
| 19 | + |
| 20 | +</div> |
| 21 | + |
| 22 | +```python |
| 23 | +import os |
| 24 | +from slack_bolt import App |
| 25 | +from slack_bolt.oauth.oauth_settings import OAuthSettings |
| 26 | +from slack_sdk.oauth.installation_store import FileInstallationStore |
| 27 | +from slack_sdk.oauth.state_store import FileOAuthStateStore |
| 28 | + |
| 29 | +oauth_settings = OAuthSettings( |
| 30 | + client_id=os.environ["SLACK_CLIENT_ID"], |
| 31 | + client_secret=os.environ["SLACK_CLIENT_SECRET"], |
| 32 | + scopes=["channels:read", "groups:read", "chat:write"], |
| 33 | + installation_store=FileInstallationStore(base_dir="./data"), |
| 34 | + state_store=FileOAuthStateStore(expiration_seconds=600, base_dir="./data") |
| 35 | +) |
| 36 | + |
| 37 | +app = App( |
| 38 | + signing_secret=os.environ["SIGNING_SECRET"], |
| 39 | + oauth_settings=oauth_settings |
| 40 | +) |
| 41 | +``` |
| 42 | + |
| 43 | +<details class="secondary-wrapper"> |
| 44 | +<summary class="section-head" markdown="0"> |
| 45 | +<h4 class="section-head">OAuth デフォルト設定をカスタマイズ</h4> |
| 46 | +</summary> |
| 47 | + |
| 48 | +<div class="secondary-content" markdown="0"> |
| 49 | +`oauth_settings` を使って OAuth モジュールのデフォルト設定を上書きすることができます。このカスタマイズされた設定は App の初期化時に渡します。以下の情報を変更可能です: |
| 50 | + |
| 51 | +- `install_path` : 「Add to Slack」ボタンのデフォルトのパスを上書きするために使用 |
| 52 | +- `redirect_uri` : リダイレクト URL のデフォルトのパスを上書きするために使用 |
| 53 | +- `callback_options` : OAuth フローの最後に表示するカスタムの成功ページと失敗ページの表示処理を提供するために使用 |
| 54 | +- `state_store` : 組み込みの `FileOAuthStateStore` に代わる、カスタムの stateに関するデータストアを指定するために使用 |
| 55 | +- `installation_store` : 組み込みの `FileInstallationStore` に代わる、カスタムのデータストアを指定するために使用 |
| 56 | + |
| 57 | +</div> |
| 58 | + |
| 59 | +```python |
| 60 | +from slack_bolt.oauth.callback_options import CallbackOptions, SuccessArgs, FailureArgs |
| 61 | +from slack_bolt.response import BoltResponse |
| 62 | + |
| 63 | +def success(args:SuccessArgs) -> BoltResponse: |
| 64 | + assert args.request is not None |
| 65 | + return BoltResponse( |
| 66 | + status=200, # ユーザーをリダイレクトすることも可能 |
| 67 | + body="Your own response to end-users here" |
| 68 | + ) |
| 69 | + |
| 70 | +def failure(args:FailureArgs) -> BoltResponse: |
| 71 | + assert args.request is not None |
| 72 | + assert args.reason is not None |
| 73 | + return BoltResponse( |
| 74 | + status=args.suggested_status_code, |
| 75 | + body="Your own response to end-users here" |
| 76 | + ) |
| 77 | + |
| 78 | +callback_options = CallbackOptions(success=success, failure=failure) |
| 79 | + |
| 80 | +import os |
| 81 | +from slack_bolt import App |
| 82 | +from slack_bolt.oauth.oauth_settings import OAuthSettings |
| 83 | +from slack_sdk.oauth.installation_store import FileInstallationStore |
| 84 | +from slack_sdk.oauth.state_store import FileOAuthStateStore |
| 85 | + |
| 86 | +app = App( |
| 87 | + signing_secret=os.environ.get("SLACK_SIGNING_SECRET"), |
| 88 | + installation_store=FileInstallationStore(base_dir="./data"), |
| 89 | + oauth_settings=OAuthSettings( |
| 90 | + client_id=os.environ.get("SLACK_CLIENT_ID"), |
| 91 | + client_secret=os.environ.get("SLACK_CLIENT_SECRET"), |
| 92 | + scopes=["app_mentions:read", "channels:history", "im:history", "chat:write"], |
| 93 | + user_scopes=[], |
| 94 | + redirect_uri=None, |
| 95 | + install_path="/slack/install", |
| 96 | + redirect_uri_path="/slack/oauth_redirect", |
| 97 | + state_store=FileOAuthStateStore(expiration_seconds=600, base_dir="./data"), |
| 98 | + callback_options=callback_options, |
| 99 | + ), |
| 100 | +) |
| 101 | +``` |
| 102 | + |
| 103 | +</details> |
0 commit comments