Repository navigation
Slack install button provided by slack does not work. Bolt/Slack-SDK appears to reject because of missing state. Is state actually optional? #248
Description
Activity
- addedquestionFurther information is requestedFurther information is requested
on Feb 26, 2021 Hi @ipl31, thanks for asking the question!
Is it mandatory in the LambdaS3AuthFlow()? If so, then how do I get the slack admin website to render links/buttons that will work?
Indeed, the
stateparameter is optional for the Slack OAuth flow but the Bolt framework is a bit opinionated. It requiresstateparameter handling as long as you use its built-in OAuth module.As described in this document, the usage is simple. Once your
Appspins up with a validOAuthSettingsargument, your app serves/slack/installpath and if your end users start the app installation from this URL, your app automatically generates and sets thestatevalue for you.@seratch Thanks. Yes I just verified that my install URL is setting the state cookie properly but the slack URL does not. Thanks for confirming this. I prefer to use the most secure option. My concern is that the slack buttons provided in the slack admin interface do not work. Once the app is approved and in the app directory will the install links from the app directory set the state properly? Or do I need to always use the install page on my app? Thanks!
@seratch I think I answered my own question after reading through how OAuth 2 works. It looks like the slack app directory must redirect to the app generated install page, since the state value needs to be stored on the app side. So it seems that the buttons/links provided by the slack admin interface will not work if you are using this feature, but the app directory will link to apps install page so its not an issue. Thanks for the response. You can close this request.
@ipl31 Thanks for confirming. Let me share a bit more about App Directory app links!
It looks like the slack app directory must redirect to the app generated install page, since the state value needs to be stored on the app side.
Once the app is approved and in the app directory will the install links from the app directory set the state properly? Or do I need to always use the install page on my app?This is a great question. For App Directory apps, you can customize the installation URL. Set the URL in Basic Information page (you'll be able to find the part if you scroll down) this way:
Also, the Bolt framework renders a simple web page for
/slack/installwith its default settings. Probably, it's not necessary in this case. You can setinstall_page_rendering_enabled=Falsein theAppconstructor (or write your own method to set anything else as necessary). see also: #183 #186Reacted by rahul@seratch thanks. That clears things up for me. Is it possible to support both scenarios. For example
/slack/installor whatever install_path is set with does not render the page, but I setup a second route (maybe/slack/install_page) that will generate the HTML and button?For example /slack/install or whatever install_path is set with does not render the page, but I setup a second route (maybe /slack/install_page) that will generate the HTML and button?
hmm, one possible way to do this is to have multiple
Appinstances with shared OAuth settings. I haven't verified if the following app works yet but doing like this is an option.Update:
install_page_rendering_enabledis part ofOAuthSettings. If you use theLambdaS3OAuthFlow, you can modify the flag like this:app = App( process_before_response=True, oauth_flow=LambdaS3OAuthFlow(), ) app.oauth_flow.settings.install_page_rendering_enabled = True direct_install_app = App( process_before_response=True, oauth_flow=LambdaS3OAuthFlow(), ) direct_install_app.oauth_flow.settings.install_page_rendering_enabled = False
If you use Flask and whatever similar, you may want to construct and pass
OAuthSettingsdirectly toAppconstructor.from slack_bolt import App from slack_bolt.oauth.oauth_settings import OAuthSettings # This App will be used for handling event requests from Slack and # /slack/oauth_redirect for both /slack/install and /slack/install_page app = App( # Use this settings except the flag oauth_settings=OAuthSettings( ..., install_page_rendering_enabled=True, ) ) # You don't need to have this method as long as you don't need to register the same set of listeners # to multiple App instances though register_listeners(app) def register_listeners(app: App) @app.event("app_mention") def handle_app_mention_events(): pass # If you prefer other framework, you can go with another one from slack_bolt.adapter.flask import SlackRequestHandler from flask import Flask, request flask_app = Flask(__name__) default_handler = SlackRequestHandler(app) @flask_app.route("/slack/events", methods=["POST"]) def events(): return default_handler.handle(request) @flask_app.route("/slack/install", methods=["GET"]) def install(): return default_handler.handle(request) @flask_app.route("/slack/oauth_redirect", methods=["GET"]) def oauth_redirect(): return default_handler.handle(request) # This app should use the same OAuth settings with the default app app_direct_install = App( # Use this settings except the flag oauth_settings=OAuthSettings( ..., install_page_rendering_enabled=False, ) ) direct_install_handler = SlackRequestHandler(app_direct_install) @flask_app.route("/slack/install_page", methods=["GET"]) def install_page(): return direct_install_handler.handle(request)
Hope this is helpful to you. This question and its answers should be helpful for others too! Thanks for taking the time to ask this 😄
@seratch thanks for the idea! One last thing :) In your comment about install_page_rendering_enabled you mentioned:
You can set install_page_rendering_enabled=False in the App constructor (or write your own method to set anything else as necessary).
Setting it in the App constructor did not work for me. Did you mean in the OAuthSettings constructor? I am going to try creating a OAuthSettings object (using env vars currently so not creating one) and passing that when I create the LambdaS3OAuthFlow() object.
Setting in OAuthSettings worked for me. Thanks again @seratch !
Oops, sorry about the error in my example! Glad to hear I could help!

Hello,
I have built a slack app using the python bolt package. It is based off the Lambda examples in bolt-python/examples. I am using the S3/Lambda Oauth class:
It is working well and I can install the app when I use the install button on my API endpoint. Which you can view here: https://slack.com/oauth/v2/authorize?client_id=1547952482821.1777332262946&scope=app_mentions:read,chat:write,commands&user_scope=
However when I attempt to use the links provided in the slack workspace admin interface, none of them work. For example:
https://slack.com/oauth/v2/authorize?client_id=1547952482821.1777332262946&scope=app_mentions:read,chat:write,commands&user_scope=
This link is provided in the slack app configuration for my app in the slack admin web app. When I attempt to use the buttons provided by slack I get redirected to my App and get an invalid browser error. Specifically "Please try again from here or contact the app owner (reason: invalid_browser)". I am using a supported browser and I am using an TLS endpoint. When I dig into the code I noticed that is_valid_browser() will return False if the state parameter is not set. Specifically this code:
https://github.com/slackapi/python-slack-sdk/blob/main/slack_sdk/oauth/state_utils/__init__.py#L44
All slack documentation says the state variable is optional but suggested for security. But this seems to indicate that it is mandatory at least with the code I am using. Is it mandatory in the LambdaS3AuthFlow()? If so, then how do I get the slack admin website to render links/buttons that will work?
Reproducible in:
bolt-python lambda oauth example, when using public distribution links from slack website.
The
slack_boltversionslack-bolt==1.4.1
slack-sdk==3.4.0
Python runtime version
(Paste the output of
python --version)Python 3.8.6
OS info
(Paste the output of
sw_vers && uname -von macOS/Linux orveron Windows OS)AWS Lambda default runtime.
Steps to reproduce:
Build the bolt-python Lambda Oauth example app. Configure the app in your slack instance. Then setup public distribution and attempt to use the install links/buttons provided by slack.
Expected result:
I expect that when I use the links generated from the slack website (under public distribution) to distribute my app, that they work. However when I use those links I get an invalid browser error. However using the link provided by my api endpoint works fine.
Actual result:
Oops, Something Went Wrong!
Please try again from here or contact the app owner (reason: invalid_browser)
Requirements
Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.