-
Notifications
You must be signed in to change notification settings - Fork 399
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e545f19
commit ffd4590
Showing
1 changed file
with
99 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
--- | ||
title: Authenticating with OAuth | ||
lang: en | ||
slug: authenticating-oauth | ||
order: 14 | ||
--- | ||
|
||
<div class="section-content"> | ||
Slack apps that are installed in multiple workspaces, like in the App Directory or in an Enterprise Grid, will need to implement OAuth and store information about each of those installations (such as access tokens). By providing `clientId`, `clientSecret`, `stateSecret` and `scopes` when initializing `App`, Bolt for JavaScript will handle the work of setting up OAuth routes and verifying state. Bolt for JavaScript's OAuth support is built on top of Slack's [OAuth library](https://slack.dev/node-slack-sdk/oauth#slack-oauth). Currently, OAuth support is only available when using Bolt for JavaScript's built-in `ExpressReceiver`. | ||
|
||
Bolt for JavaScript will create a **Redirect URL** `slack/oauth_redirect`, which is used by Slack to redirect users after they grant access for you app to be installed in their workspace. You will need to add this **Redirect URL** in your app configuration settings under **OAuth and Permissions**. | ||
|
||
Bolt for JavaScript will also create a `slack/install` route, where you can find an `Add to Slack` button for your app to do direct installs of the app. If you need an additional authorizations (user tokens) from users inside a team when your app is already installed or a reason to dynamically generate an install URL, you can generate it via `app.installer.generateInstallUrl()`. Read more about `generateInstallUrl()` in the [OAuth docs](https://slack.dev/node-slack-sdk/oauth#generating-an-installation-url). | ||
</div> | ||
|
||
```javascript | ||
const app = new App({ | ||
signingSecret: process.env.SLACK_SIGNING_SECRET, | ||
clientId: process.env.SLACK_CLIENT_ID, | ||
clientSecret: process.env.SLACK_CLIENT_SECRET | ||
stateSecret: 'my-state-secret', | ||
scopes: ['channels:read', 'groups:read', 'channels:manage', 'chat:write', 'incoming-webhook'], | ||
installationStore: { | ||
storeInstallation: (installation) => { | ||
// change the line below so it saves to your database | ||
return database.set(installation.team.id, installation); | ||
}, | ||
fetchInstallation: (InstallQuery) => { | ||
// change the line below so it fetches from your database | ||
return database.get(InstallQuery.teamId); | ||
}, | ||
}, | ||
}); | ||
``` | ||
|
||
<details class="secondary-wrapper"> | ||
<summary class="section-head" markdown="0"> | ||
<h4 class="section-head">Customizing OAuth defaults</h4> | ||
</summary> | ||
|
||
<div class="secondary-content" markdown="0"> | ||
The OAuth support in Bolt comes with a variety of defaults. We do provide a way to override these defaults with the `installerOptions` object which can be passed in during the initialization of `App`. You can override the following: | ||
|
||
- `authVersion`: Used to toggle between new Slack Apps and Classic Slack Apps | ||
- `metadata`: Used to pass around session related information | ||
- `installPath`: Override default path for "Add to Slack" button | ||
- `redirectUriPath`: Override default redirect url path | ||
- `callbackOptions`: Provide custom success and failure pages at the end of the OAuth flow | ||
- `stateStore`: Provide a custom state store instead of using the built in `ClearStatStore` | ||
|
||
</div> | ||
|
||
```javascript | ||
const app = new App({ | ||
signingSecret: process.env.SLACK_SIGNING_SECRET, | ||
clientId: process.env.SLACK_CLIENT_ID, | ||
clientSecret: process.env.SLACK_CLIENT_SECRET | ||
scopes: ['channels:read', 'groups:read', 'channels:manage', 'chat:write', 'incoming-webhook'], | ||
installerOptions: { | ||
authVersion: 'v1', // default is 'v2', 'v1' is used for classic slack apps | ||
metadata: 'some session data', | ||
installPath: 'slack/installApp', | ||
redirectUriPath: 'slack/redirect', | ||
callbackOptions: { | ||
success: (installation, installOptions, req, res) => { | ||
// Do custom success logic here | ||
res.send('successful!'); | ||
}, | ||
failure: (error, installOptions , req, res) => { | ||
// Do custom failure logic here | ||
res.send('failure'); | ||
} | ||
}, | ||
stateStore: { | ||
// Do not need to provide a `stateSecret` when passing in a stateStore | ||
// generateStateParam's first argument is the entire InstallUrlOptions object which was passed into generateInstallUrl method | ||
// the second argument is a date object | ||
// the method is expected to return a string representing the state | ||
generateStateParam: (installUrlOptions, date) => { | ||
// generate a random string to use as state in the URL | ||
const randomState = randomStringGenerator(); | ||
// save installOptions to cache/db | ||
myDB.set(randomState, installUrlOptions); | ||
// return a state string that references saved options in DB | ||
return randomState; | ||
}, | ||
// verifyStateParam's first argument is a date object and the second argument is a string representing the state | ||
// verifyStateParam is expected to return an object representing installUrlOptions | ||
verifyStateParam: (date, state) => { | ||
// fetch saved installOptions from DB using state reference | ||
const installUrlOptions = myDB.get(randomState); | ||
return installUrlOptions; | ||
} | ||
}, | ||
} | ||
}); | ||
``` | ||
|
||
</details> |