Flask-Discord
Flask-Discord copied to clipboard
Secret doesn't end up in JWT
Some Contextual Information: Python v3.10 JWT v.2.6.0 OS: Ubuntu
Firstly, I am constructing a DiscordOAuth2Session()
like so (I have shuffled up all the values to protect my application):
app = Flask(__name__)
app.config["SECRET_KEY"] = 'os.urandom(24)'
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "true"
app.config["DISCORD_CLIENT_ID"] = 398041555473157536
app.config["DISCORD_CLIENT_SECRET"] = "LQYn4UiOgyIJspje6Y1aueKwK2Ccwput"
app.config["DISCORD_REDIRECT_URI"] = "http://mysite.net/callback/"
app.config["DISCORD_BOT_TOKEN"] = "QNkkzNjoyODgzFzE2EzU4MjI1.BVHlrQ.kdCdDeAKzFXYByMkB3_zVIaosQrQFO4Us6tjdQ"
discord = DiscordOAuth2Session(app)
I then specify my callback address and input it into the Discord Developer Panel:
@app.route("/callback/")
def callback():
discord.callback()
user = discord.fetch_user()
return redirect('/')
@app.errorhandler(Unauthorized)
def redirect_unauthorized(e):
return redirect(url_for("login"))
Upon trying to access a @requires_authorization
location on my site, I am redirected to the Discord OAuth screen, perfect so far. All the information displayed on this screen is correct.
As soon as I click "Authorize," I am redirected to what appears to be the correct location on my website, with a Flask traceback indicating some sort of problem with JWT.
The traceback:
Traceback (most recent call last):
File "/home/ubuntu/.local/lib/python3.10/site-packages/jwt/api_jws.py", line 251, in _load
signing_input, crypto_segment = jwt.rsplit(b".", 1)
ValueError: not enough values to unpack (expected 2, got 1)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/ubuntu/.local/lib/python3.10/site-packages/flask/app.py", line 2548, in __call__
return self.wsgi_app(environ, start_response)
File "/home/ubuntu/.local/lib/python3.10/site-packages/flask/app.py", line 2528, in wsgi_app
response = self.handle_exception(e)
File "/home/ubuntu/.local/lib/python3.10/site-packages/flask/app.py", line 2525, in wsgi_app
response = self.full_dispatch_request()
File "/home/ubuntu/.local/lib/python3.10/site-packages/flask/app.py", line 1822, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/ubuntu/.local/lib/python3.10/site-packages/flask/app.py", line 1820, in full_dispatch_request
rv = self.dispatch_request()
File "/home/ubuntu/.local/lib/python3.10/site-packages/flask/app.py", line 1796, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "/home/ubuntu/discord_bot/web/flask/main.py", line 48, in callback
discord.callback()
File "/home/ubuntu/.local/lib/python3.10/site-packages/flask_discord/client.py", line 161, in callback
return jwt.decode(state, current_app.config["SECRET_KEY"], algorithms="HS256")
File "/home/ubuntu/.local/lib/python3.10/site-packages/jwt/api_jwt.py", line 168, in decode
decoded = self.decode_complete(
File "/home/ubuntu/.local/lib/python3.10/site-packages/jwt/api_jwt.py", line 120, in decode_complete
decoded = api_jws.decode_complete(
File "/home/ubuntu/.local/lib/python3.10/site-packages/jwt/api_jws.py", line 191, in decode_complete
payload, signing_input, header, signature = self._load(jwt)
File "/home/ubuntu/.local/lib/python3.10/site-packages/jwt/api_jws.py", line 254, in _load
raise DecodeError("Not enough segments") from err
jwt.exceptions.DecodeError: Not enough segments
It's hard for me to tell exactly what is wrong, as I am not very good at cracking modules open myself, but this is what I was able to find.
- The issue occurs when processing
app.config["SECRET_KEY"]
tojwt.decode()
- The key displays just fine when
print(f'SECRET AS SEEN IN client.py: {current_app.config["SECRET_KEY"]}')
is ran on line 159 ofclient.py
inFlask-Discord
-
print(jwt)
outputsb''
when ran on line 250 ofapi_jws.py
injwt
I've tried several different types of secrets to no avail, and I am currently torn between this being my own error or not. If someone has more details, please let me know.
Check if this helps https://github.com/weibeu/Flask-Discord/issues/56#issuecomment-985147104 Additionally, re-check just in case that your callback URL configured in config and that on dashboard are exactly same. Including http/https URL scheme
I feel fairly confident that I have done this part correctly, but anything is possible when I take on a project. Here's what I have:
In main.py
:
app.config["DISCORD_REDIRECT_URI"] = "http://XXXXX.net/callback/"
On my Discord Developer Dashboard:
http://XXXXX.net/callback/
What appears in the addressbar after I click "Authorize":
http://XXXXX.net/callback/?code=NfqYd9YQqieAGCEjHhhHUeXceBr3hz&state=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfX3N0YXRlX3NlY3JldF8iOiJxQTV5dzU2dHZoY0VMVXI5TmJ2c052NVlqTW5ieEQifQ.DxB1RwizZnLMBFikrGkEQf5OKvFy4QLgrNXu_kKuGuM
My @app.route()
:
@app.route("/callback/")
def callback():
discord.callback() # <--- Error occurs here according to traceback
user = discord.fetch_user()
return redirect('/')
Setting my secret key:
app.config["SECRET_KEY"] = os.urandom(24)
Some newfound information.
In callback(self)
at line 142, self.__get_state()
returns nothing. If I try to print it, it's an empty string, which leads me to believe that this item is not in my session when it is called? That would explain why there isn't enough segments when it's passed to jwt.decode()
Sounds either of the following or something similar could be happening:
- The cookie isn't being set for some reason. Which is done when calling discord.create_session method.
- The cookie is being set but it isn't accessible or found or sent when the user is redirected to your callback endpoint.
- Few more possible reasons I couldn't think of.
Hello @Mister-SOSA - If you still need this to be fixed, you need to change this line. https://github.com/weibeu/Flask-Discord/pull/74