slackapi / bolt-js

A framework to build Slack apps using JavaScript
https://slack.dev/bolt-js
MIT License
2.73k stars 390 forks source link

Error on /slack/oauth_redirect using ExpressReceiver (bolt-js v3.9) #1529

Closed julishaka closed 2 years ago

julishaka commented 2 years ago

Description

Hi, I'm getting this error when my app redirects to slack/oauth_redirect. I've looked at #1335 but I can't tell if its the same problem. The URLs are all https ones. I recently started using expressReceiver in order to be able to accept post requests from an external source. However, I may be using it incorrectly and thinking all wrong. Any help would be appreciated. Thank you.

[ERROR]  OAuth:InstallProvider:0 Error: The state parameter is not for this browser session.
    at new InvalidStateError (/Users/shakauser/Desktop/shaka-slack-bot/slack-app/node_modules/@slack/oauth/dist/errors.js:65:47)
    at InstallProvider.<anonymous> (/Users/shakauser/Desktop/shaka-slack-bot/slack-app/node_modules/@slack/oauth/dist/install-provider.js:498:39)
    at step (/Users/shakauser/Desktop/shaka-slack-bot/slack-app/node_modules/@slack/oauth/dist/install-provider.js:44:23)
    at Object.next (/Users/shakauser/Desktop/shaka-slack-bot/slack-app/node_modules/@slack/oauth/dist/install-provider.js:25:53)
    at /Users/shakauser/Desktop/shaka-slack-bot/slack-app/node_modules/@slack/oauth/dist/install-provider.js:19:71
    at new Promise (<anonymous>)
    at __awaiter (/Users/shakauser/Desktop/shaka-slack-bot/slack-app/node_modules/@slack/oauth/dist/install-provider.js:15:12)
    at InstallProvider.handleCallback (/Users/shakauser/Desktop/shaka-slack-bot/slack-app/node_modules/@slack/oauth/dist/install-provider.js:462:16)
    at /Users/shakauser/Desktop/shaka-slack-bot/slack-app/node_modules/@slack/bolt/dist/receivers/ExpressReceiver.js:166:42
    at Layer.handle [as handle_request] (/Users/shakauser/Desktop/shaka-slack-bot/slack-app/node_modules/express/lib/router/layer.js:95:5) {
  code: 'slack_oauth_invalid_state'
const receiver = new ExpressReceiver({ 
  token: process.env.SLACK_BOT_TOKEN,
  appToken: process.env.SLACK_APP_TOKEN,
  port: process.env.PORT || 3030,
  signingSecret: process.env.SLACK_SIGNING_SECRET,
  clientId: process.env.SLACK_CLIENT_ID,
  clientSecret: process.env.SLACK_CLIENT_SECRET,
  stateSecret: 'some-shaka-state-secret',
  scopes: scopes,
  installationStore: {
    storeInstallation: async (installation) => {
      // change the line below so it saves to your database
      if (installation.isEnterpriseInstall && installation.enterprise !== undefined) {
        // support for org wide app installation
        return await database.set(installation.enterprise.id, installation);
      }
      if (installation.team !== undefined) {
        // single team app installation
        return await database.set(installation.team.id, installation);
      }
      throw new Error('Failed saving installation data to installationStore');
    },
    fetchInstallation: async (installQuery) => {
      // change the line below so it fetches from your database
      if (installQuery.isEnterpriseInstall && installQuery.enterpriseId !== undefined) {
        // org wide app installation lookup
        return await database.get(installQuery.enterpriseId);
      }
      if (installQuery.teamId !== undefined) {
        // single team app installation lookup
        return await database.get(installQuery.teamId);
      }
      throw new Error('Failed fetching installation');
    },
    deleteInstallation: async (installQuery) => {
      // change the line below so it deletes from your database
      if (installQuery.isEnterpriseInstall && installQuery.enterpriseId !== undefined) {
        // org wide app installation deletion
        return await database.delete(installQuery.enterpriseId);
      }
      if (installQuery.teamId !== undefined) {
        // single team app installation deletion
        return await database.delete(installQuery.teamId);
      }
      throw new Error('Failed to delete installation');
    },
  },
  installerOptions: {
    // If this is true, /slack/install redirects installers to the Slack authorize URL
    // without rendering the web page with "Add to Slack" button.
    // This flag is available in @slack/bolt v3.7 or higher
    directInstall: true,
  }
});

receiver.router.use(express.json());
receiver.router.use(cors());

const app = new App({
  receiver,
  logLevel: LogLevel.DEBUG,
});

receiver.router.get('/', (req, res) => {
  res.writeHead(200);
  res.end('Home Page!');
});

receiver.router.post('/shaka-events', (req, res) => {
  res.json(req.body); 
  console.log(req.body);
});

What type of issue is this? (place an x in one of the [ ])

Requirements (place an x in each of the [ ])

seratch commented 2 years ago

Hi @julishaka, thanks for writing in. I've checked whether your app works for me and it works without any issues.

Since your /slack/oauth_redirect browser access has the state parameter in its query string, you should start the OAuth flow from /slack/install. The only possible causes that I think of are:

I would suggest checking the details of HTTP request / response during your OAuth flow. You can check those information using your web browser's inspector and curl https://{your public domain}/slack/install -v. I hope you will figure the cause out soon!

julishaka commented 2 years ago

Hi @seratch, thank you for the quick response. Do you know of any reasons why the app wouldn't set cookies? I'm not sure what to look for when checking the details of HTTP request / response.

But I haven't visited /slack/oauth_redirect directly multiple times. I always start the OAuth flow from /slack/install. I don't think I've run multiple OAuth flows in the same browser at a time. If I did, the would the error go away just by closing tabs?

Thank you

seratch commented 2 years ago

I'm not sure what to look for when checking the details of HTTP request / response. You can verify the set-cookie headers in the /slack/install response and cookie header in the /slack/oauth_redirect request are valid.

Also, do you use the latest versions of @slack/bolt and @slack/oauth for sure? @slack/oauth@2.5.0 ~ 2.5.1 had a bug on setting cookies logic: https://github.com/slackapi/node-slack-sdk/pull/1485

julishaka commented 2 years ago

I'm not suite sure what you mean by valid. This is what I see. Also, yes @slack/bolt version 3.9.0 and @slack/oauth version 2.5.4 slack/install:

image

/slack/oauth_redirect:

image
seratch commented 2 years ago

@julishaka Thanks for sharing the details. The cause must be the old version of bolt that you are using. Please upgrade to 3.11.0 or newer. The latest version as of today is 3.12.1.

julishaka commented 2 years ago

Oh my goodness that fixed it. Thank you so much for taking the time to help me!

seratch commented 2 years ago

Glad to hear that! Let me close this issue now