Skip to content

Commit

Permalink
added oauth docs
Browse files Browse the repository at this point in the history
  • Loading branch information
stevengill committed May 11, 2020
1 parent 3990a5e commit b29c6bd
Showing 1 changed file with 99 additions and 0 deletions.
99 changes: 99 additions & 0 deletions docs/_basic/authenticating_oauth.md
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>

0 comments on commit b29c6bd

Please sign in to comment.