Code Monkey home page Code Monkey logo

flask-discord's Introduction

Flask-Discord

PyPI Read the Docs Discord

Discord OAuth2 extension for Flask.

Installation

To install current latest release you can use following command:

python3 -m pip install Flask-Discord

Basic Example

import os

from flask import Flask, redirect, url_for
from flask_discord import DiscordOAuth2Session, requires_authorization, Unauthorized

app = Flask(__name__)

app.secret_key = b"random bytes representing flask secret key"
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "true"      # !! Only in development environment.

app.config["DISCORD_CLIENT_ID"] = 490732332240863233    # Discord client ID.
app.config["DISCORD_CLIENT_SECRET"] = ""                # Discord client secret.
app.config["DISCORD_REDIRECT_URI"] = ""                 # URL to your callback endpoint.
app.config["DISCORD_BOT_TOKEN"] = ""                    # Required to access BOT resources.

discord = DiscordOAuth2Session(app)


@app.route("/login/")
def login():
    return discord.create_session()
	

@app.route("/callback/")
def callback():
    discord.callback()
    return redirect(url_for(".me"))


@app.errorhandler(Unauthorized)
def redirect_unauthorized(e):
    return redirect(url_for("login"))

	
@app.route("/me/")
@requires_authorization
def me():
    user = discord.fetch_user()
    return f"""
    <html>
        <head>
            <title>{user.name}</title>
        </head>
        <body>
            <img src='{user.avatar_url}' />
        </body>
    </html>"""


if __name__ == "__main__":
    app.run()

For an example to the working application, check test_app.py

Requirements

  • Flask
  • requests_oauthlib
  • cachetools
  • discord.py

Documentation

Head over to documentation for full API reference.

flask-discord's People

Contributors

a-trash-coder avatar dependabot[bot] avatar dorilahav avatar harryet avatar predaaa avatar virusmater avatar weibeu avatar williamhatcher avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

flask-discord's Issues

does the example bot work with locahost?

i am using your example, and have updated it with my tokens etc to get started.
whenever i access the the page via localhost or its local ip, i get Invalid oAuth2 redirect_uri

does this uri need to be publicly accessible for this example to work?

Discord Authorization in react app not working with flask backend

So I am trying to set up a flask backend through which i want to do discord authorization in my react app.
my flask backed looks like this:

@application.route("/login/")
def login():
    discordSession = discord.create_session(scope=["identify"])
    return discordSession


# function to redirect to discord oauth page.
@application.route("/callback")
def callback():
    try:
        data = discord.callback()
      
        redirect_to = data.get("redirect", REDIRECT_URL)
        # user = discord.fetch_user()
        print(redirect_to)
        return redirect_to
    except AccessDenied:
        return redirect(url_for("index"))


@application.route("/discordInfo")
def discordInfo():
    if not discord.authorized:
        # return render_template('loginPage.html')  # rendering index.html file
        return jsonify({"isAuthorized": False})
    user = discord.fetch_user()
    av = user.avatar_url if user.avatar_url else user.default_avatar_url
    userID = str(user.id)
    encryptedID = encrypt_message(userID).decode()
    data = {
        "isAuthorized": True,
        "username": user.name + "#" + user.discriminator,
        "stringID": encryptedID,
        "avatarUrl": av
    }
    return jsonify(data)

and the frontend code for login button is this:

<button
 onClick={async () => {
window.location.replace("http://127.0.0.1:5000/login/");
  }>
          discord login
</button>

when i click the discord login button, the login session starts.
image
When i click authorize, I am redirected to the redirect URI I have set but that URL also has some extra queries like this
http://localhost:3000/?code=KqntCqGvR1kWRckoeNZiNoUePQqpvp&state=eyJ0eXipOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfX3N0YXRlX3NlY3JldF8iOiJodk1xcjuwc1dDVlZKMGIzUWdXNkExYTRUZ1I1NWgifQ.As-hU5qrnGZ-q4ghRi2JonTcuuJmg1uMIBcDYgI-zD8

After login, i want to hit /discordInfo to get user information but it always returns {"isAuthorized": False}

Can anyone help me figuring out what I am doing wrong?

Blueprint Support

Hey, I need to use Flask-Discord in a blueprint but I am not sure if that is possible.

I get the error AttributeError: 'Flask' object has no attribute 'discord' and I think its because it uses current_app instead of the blueprint itself.

Thanks

Not authorized even though I authorized access to my account

I am trying to implement sign-in with Discord on a website I am making.
if discord.authorized == False: return redirect(URL BACK TO LOGIN PAGE) else: return <p>You passed authorization</p> #This is just for testing purposes

And on every case, it redirects me back to Discord's "Authorize access to your account" page.

The login code (Pretty much copy-pasted from the guide)
`@app.route('/')
def login():
return discord.create_session()

@app.route("/callback/")
def callback():
discord.callback()
return redirect(url_for(".me"))`

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"))

image

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"] to jwt.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 of client.py in Flask-Discord
  • print(jwt) outputs b'' when ran on line 250 of api_jws.py in jwt

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.

InSecure Transport error

Hi, i start my discord app on flask ngrok server and try ro run it
but I got such an error ... What should I do, tell me please?
ะธะทะพะฑั€ะฐะถะตะฝะธะต

Flask Discord create bot invite?

Can the feature of creating invites using flask-discord be added?
Cause discord redirect URI is broken when you use the discord developer portal.

Error `flask_discord.exceptions.Unauthorized` with proper token

I am playing around with flask-discord.
I am having problems with authenication.
Here's code if it help.

import os

from flask import Flask, redirect, url_for, request, render_template, jsonify, send_from_directory
from flask_discord import DiscordOAuth2Session, requires_authorization, Unauthorized

app = Flask(__name__)

app.config["DISCORD_CLIENT_ID"] = 912743909959020617
app.config["DISCORD_CLIENT_SECRET"] = "client secret here"
app.config["DISCORD_REDIRECT_URI"] = "http://localhost:5000/dr"

try:
    with open('token.txt', 'r') as f:
        token = f.read()
except FileNotFoundError:
    token = input("Enter token: ")
    with open('token.txt', 'w') as f:
        f.write(token)

app.config["DISCORD_BOT_TOKEN"] = token
print(token)
discord = DiscordOAuth2Session(app,app.config["DISCORD_CLIENT_ID"],app.config["DISCORD_CLIENT_SECRET"],bot_token=app.config["DISCORD_BOT_TOKEN"])

@app.route('/')
def index():
    open('log.txt','w').write(str(discord.fetch_guilds()))
    return render_template('index.html',servers=len(discord.fetch_guilds()),users=len(discord.fetch_users()))

@app.route('/css/<file>')
def css(file):
    return send_from_directory('static/css', file)

@app.route('/assets/<file>')
def assets(file):
    return send_from_directory('static/assets', file)

@app.route('/js/<file>')
def js(file):
    return send_from_directory('static/js', file)

app.run(debug=True)

Provide async views support

Provide support for Flask async views as outlined in https://flask.palletsprojects.com/en/2.0.x/async-await/

Theoretically it should be as easy as adding current_app.ensure_sync(func) to decorators, so I tried adding it myself, but I faced issues, which seemed to boil down to it working on the first loading of the site, but after any refresh or navigating to a different page with @requires_authorization the site would just crash.

Thanks!

Unauthorised when trying to get guild roles

I'm trying to get the guild roles using DiscordOAuth2Session.request, and I'm getting an unauthorised error. I'm guessing this is because my application itself doesn't have authorisation to view the roles, how could I get the roles of a guild in this situation?

CSRF Warning! State not equal in request and response.

Hello and happy new year!

I have tried for few hours to understand what is going on and yet im coming nowhere!

I did something super simple such as:

import os

from flask import Flask, redirect, url_for
from flask_discord import DiscordOAuth2Session, requires_authorization, Unauthorized

app = Flask(__name__)

app.secret_key = b"random bytes representing flask secret key"
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "true"  # !! Only in development environment.

# Random ids, so its safe!

app.config["DISCORD_CLIENT_ID"] = 7874414230411123123  # Discord client ID.
app.config["DISCORD_CLIENT_SECRET"] = "AwfaefaefafaZqYO6B97TF_sefesfeafesij!"  # Discord client secret.
app.config["DISCORD_REDIRECT_URI"] = "http://127.0.0.1:5000/callback/"  # URL to your callback endpoint.
app.config["DISCORD_BOT_TOKEN"] = "Nzg3NsrgsgsgsgY3MzYw.X9U_-Q._ehaefaagagt7bdf-E"  # Required to access BOT resources.

discord = DiscordOAuth2Session(app)


@app.route("/login/")
def login():
    test = discord.create_session()
    return test


@app.route("/callback/")
def callback():
    discord.callback()
    return redirect(url_for(".me"))


@app.errorhandler(Unauthorized)
def redirect_unauthorized(e):
    return redirect(url_for("login"))


@app.route("/me/")
@requires_authorization
def me():
    user = discord.fetch_user()
    return f"""
    <html>
        <head>
            <title>{user.name}</title>
        </head>
        <body>
            <img src='{user.avatar_url}' />
        </body>
    </html>"""


if __name__ == "__main__":
    app.run()

and in discord devs website:

image

Whenever I try to access http://127.0.0.1:5000/login/ -> it asks me to identify myself through discord and then once that is done, it gives me an error with following information:

127.0.0.1 - - [30/Dec/2020 20:53:50] "GET /login/ HTTP/1.1" 302 -
[2020-12-30 20:53:52,869] ERROR in app: Exception on /callback/ [GET]
Traceback (most recent call last):
  File "C:\Users\Barry-PC\AppData\Roaming\Python\Python38\site-packages\flask\app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\Barry-PC\AppData\Roaming\Python\Python38\site-packages\flask\app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\Barry-PC\AppData\Roaming\Python\Python38\site-packages\flask\app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\Barry-PC\AppData\Roaming\Python\Python38\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "C:\Users\Barry-PC\AppData\Roaming\Python\Python38\site-packages\flask\app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\Barry-PC\AppData\Roaming\Python\Python38\site-packages\flask\app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:/Projects/test.py", line 28, in callback
    discord.callback()
  File "C:\Users\Barry-PC\AppData\Local\Programs\Python\Python38\lib\site-packages\flask_discord\client.py", line 157, in callback
    token = self._fetch_token(state)
  File "C:\Users\Barry-PC\AppData\Local\Programs\Python\Python38\lib\site-packages\flask_discord\_http.py", line 93, in _fetch_token
    return discord.fetch_token(
  File "C:\Users\Barry-PC\AppData\Local\Programs\Python\Python38\lib\site-packages\requests_oauthlib\oauth2_session.py", line 239, in fetch_token
    self._client.parse_request_uri_response(
  File "C:\Users\Barry-PC\AppData\Local\Programs\Python\Python38\lib\site-packages\oauthlib\oauth2\rfc6749\clients\web_application.py", line 203, in parse_request_uri_response
    response = parse_authorization_code_response(uri, state=state)
  File "C:\Users\Barry-PC\AppData\Local\Programs\Python\Python38\lib\site-packages\oauthlib\oauth2\rfc6749\parameters.py", line 268, in parse_authorization_code_response
    raise MismatchingStateError()
oauthlib.oauth2.rfc6749.errors.MismatchingStateError: (mismatching_state) CSRF Warning! State not equal in request and response.
127.0.0.1 - - [30/Dec/2020 20:53:52] "GET /callback/?code=eavmRSh3BYILRzGYHrr3L4dBy4Tcwu&state=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfX3N0YXRlX3NlY3JldF8iOiI4azd1dk92dUQyc0hKUU5QbU4xNDJpcjY2RjdjdDgifQ.BBGuWC1OH8Sw-CMqprFKnibclJZTQnW6NDlekXfD8rA HTTP/1.1" 500 -

im not sure what im doing wrong but I assume it is most likely my end that is wrong but no idea why :D

TypeError: Expected a string value

The code below always gives me the error TypeError: Expected a string value. Something in the flask-discord module itself is causing this error because I'm just doing exactly what the documentation says.

@app.route('/login')
def login():
    return auth.create_session()

Error:

[2021-10-30 09:39:27,372] ERROR in app: Exception on /login [GET]
Traceback (most recent call last):
  File "C:\Users\janva\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 2070, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\janva\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1515, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\janva\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1513, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\janva\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1499, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "C:\Users\janva\PycharmProjects\webtest\app.py", line 25, in login
    return auth.create_session()
  File "C:\Users\janva\AppData\Local\Programs\Python\Python39\lib\site-packages\flask_discord\client.py", line 99, in create_session
    state = jwt.encode(data, current_app.config["SECRET_KEY"], algorithm="HS256")
  File "C:\Users\janva\AppData\Local\Programs\Python\Python39\lib\site-packages\jwt\api_jwt.py", line 63, in encode
    return api_jws.encode(json_payload, key, algorithm, headers, json_encoder)
  File "C:\Users\janva\AppData\Local\Programs\Python\Python39\lib\site-packages\jwt\api_jws.py", line 110, in encode
    key = alg_obj.prepare_key(key)
  File "C:\Users\janva\AppData\Local\Programs\Python\Python39\lib\site-packages\jwt\algorithms.py", line 180, in prepare_key
    key = force_bytes(key)
  File "C:\Users\janva\AppData\Local\Programs\Python\Python39\lib\site-packages\jwt\utils.py", line 21, in force_bytes
    raise TypeError("Expected a string value")
TypeError: Expected a string value
127.0.0.1 - - [30/Oct/2021 09:39:27] "GET /login HTTP/1.1" 500 -

Package dependencies are too strict

In 0985cb2 the install_requires of the package was updated to require specific versions of all dependencies, recursively.

For testing this package itself, locking that way is great. But for downstream packages this at best prevents me from updating any of these packages, at worst causes conflicts with other packages.

Missing Acess Token parameter

I received this while using my app normally:

[2022-02-25 14:36:08,237] ERROR in app: Exception on /callback/ [GET]
Traceback (most recent call last):
  File "/home/runner/SomelistAPI/venv/lib/python3.8/site-packages/flask/app.py", line 2073, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/runner/SomelistAPI/venv/lib/python3.8/site-packages/flask/app.py", line 1518, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/runner/SomelistAPI/venv/lib/python3.8/site-packages/flask_cors/extension.py", line 165, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/home/runner/SomelistAPI/venv/lib/python3.8/site-packages/flask/app.py", line 1516, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/runner/SomelistAPI/venv/lib/python3.8/site-packages/flask/app.py", line 1502, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "main.py", line 74, in callback
    discord.callback()
  File "/home/runner/SomelistAPI/venv/lib/python3.8/site-packages/flask_discord/client.py", line 156, in callback
    token = self._fetch_token(state)
  File "/home/runner/SomelistAPI/venv/lib/python3.8/site-packages/flask_discord/_http.py", line 93, in _fetch_token
    return discord.fetch_token(
  File "/home/runner/SomelistAPI/venv/lib/python3.8/site-packages/requests_oauthlib/oauth2_session.py", line 366, in fetch_token
    self._client.parse_request_body_response(r.text, scope=self.scope)
  File "/home/runner/SomelistAPI/venv/lib/python3.8/site-packages/oauthlib/oauth2/rfc6749/clients/base.py", line 448, in parse_request_body_response
    self.token = parse_token_response(body, scope=scope)
  File "/home/runner/SomelistAPI/venv/lib/python3.8/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 441, in parse_token_response
    validate_token_parameters(params)
  File "/home/runner/SomelistAPI/venv/lib/python3.8/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 451, in validate_token_parameters
    raise MissingTokenError(description="Missing access token parameter.")
oauthlib.oauth2.rfc6749.errors.MissingTokenError: (missing_token) Missing access token parameter.

I can confirm that the token, client_id, and client_secrets are all valid and correct.

How do I solve this problem then?

discord.revoke() error

If you create a session then run discord.revoke() it works fine, but if you restart your Flask environment and you remain logged in, and then try to run discord.revoke() you get

File "C:\Users\XXX\XXX\app.py", line 25, in logout
    discord.revoke()
  File "C:\Users\XXX\XXX\venv\lib\site-packages\flask_discord\client.py", line 66, in revoke
    session.pop(session_key)
  File "C:\Users\XXX\XXX\venv\lib\site-packages\werkzeug\datastructures.py", line 270, in pop
    rv = super(UpdateDictMixin, self).pop(key)
KeyError: 'DISCORD_OAUTH2_STATE'

I can temporarily work around this by replacing your session.pop code with session.clear() but would like to see a permanent fix.

Invalid OAuth2 access token

def add_to_server(access_token, server_id, user_id):

    url = 'https://discordapp.com/api/guilds/{}/members/{}'.format(server_id, user_id)

    headers = {
        'Authorization': 'Bot XXXXXXXXXXXXXXXXXXXXX',
        'Content-Type': 'application/json'
    }

    data = {
        'access_token': access_token
    }

    add = requests.put(url, headers=headers, json=data)
    print(json.loads(add.text))

This gives:
{'message': 'Invalid OAuth2 access token', 'code': 50025}

To get the access token and user_id I use:

access_token = session['DISCORD_OAUTH2_TOKEN']['access_token']
user = discord.fetch_user() 
user_id = user.id

Any idea on how to fix this? Thanks in advance.

Revoke Oauth connection

The revoke method of DiscordOAuth2Session doesn't revoke the Oauth access, i.e. the user's discord connections screen will still show the oauth app even if revoke is called.

def revoke(self):
"""This method clears current discord token, state and all session data from flask
`session <http://flask.pocoo.org/docs/1.0/api/#flask.session>`_. Which means user will have
to go through discord authorization token grant flow again. Also tries to remove the user from internal
cache if they exist.
"""
self.users_cache.pop(self.user_id, None)
for session_key in self.SESSION_KEYS:
try:
session.pop(session_key)
except KeyError:
pass

Token Revocation can be done by making a request to - https://discord.com/api/oauth2/token/revoke

I'm interested in contributing to this fix.

Include list of keys used from configs in documentation.

Flask-Discord makes use of the Flask config for few configurations values like Discord application client ID, secret, etc. and more. However, the documentation is missing list and description about all of the keys used by the library.

Describing them in the documentation might be helpful to the library users to better fine tune it as for their needs.

Quick way to find them is to look for config[" in the project files.

jwt.exceptions.DecodeError: Not enough segments

import os, random, string
2	from dotenv import dotenv_values
3	from flask import Flask, redirect, url_for, render_template
4	from flask_discord import DiscordOAuth2Session, requires_authorization, Unauthorized
5	import github_utils, db_utils# local files
6	
7	app = Flask(__name__)
8	
9	app.secret_key = bytes(''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(64)), 'utf-8')
10	# OAuth2 must make use of HTTPS in production environment.
11	# os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "true"      # !! Only in development environment.
12	# os.environ["FLASK_ENV"] = "development"
13	
14	config = dotenv_values(".env")
15	
16	app.config["DISCORD_CLIENT_ID"] = config["DISCORD_CLIENT_ID"]
17	app.config["DISCORD_CLIENT_SECRET"] = config["DISCORD_CLIENT_SECRET"]
18	app.config["DISCORD_REDIRECT_URI"] = "https://altab.dev/callback"
19	# app.config["DISCORD_BOT_TOKEN"] = config["DISCORD_BOT_TOKEN"]
20	
21	discord = DiscordOAuth2Session(app)
22	
23	def welcome_user(user):
24	dm_channel = discord.bot_request("/users/@me/channels", "POST", json={"recipient_id": user.id})
25	return discord.bot_request(
26	    f"/channels/{dm_channel['id']}/messages", "POST", json={"content": "Thanks for authorizing the app!"}
27	)
28	
29	@app.route("/")
30	def index():
31	return render_template("index.html", repos=github_utils.get_repos_list(), users=db_utils.get_users())
32	
33	@app.route("/login/")
34	def login():
35	return discord.create_session()
36	
37	@app.route("/callback/")
38	def callback():
39	discord.callback()
40	user = discord.fetch_user()
41	welcome_user(user)
42	return redirect(url_for(".me"))
43	
44	
45	@app.errorhandler(Unauthorized)
46	def redirect_unauthorized(e):
47	return redirect(url_for("login"))
48	
49	
50	@app.route("/me/")
51	@requires_authorization
52	def me():
53	user = discord.fetch_user()
54	if not db_utils.user_exists(str(user.id)):
55	    db_utils.add_user(str(user.id), str(user.username), str(user.avatar_url))
56	return render_template("welcome.html", pic=user.avatar_url, username=user.username)
57	
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]: Traceback (most recent call last):
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:   File "/var/www/Portfolio/env3/lib/python3.6/site-packages/flask/app.py", line 2070, in wsgi_app
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:     response = self.full_dispatch_request()
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:   File "/var/www/Portfolio/env3/lib/python3.6/site-packages/flask/app.py", line 1515, in full_dispatch_request
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:     rv = self.handle_user_exception(e)
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:   File "/var/www/Portfolio/env3/lib/python3.6/site-packages/flask/app.py", line 1513, in full_dispatch_request
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:     rv = self.dispatch_request()
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:   File "/var/www/Portfolio/env3/lib/python3.6/site-packages/flask/app.py", line 1499, in dispatch_request
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:     return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:   File "/var/www/Portfolio/app.py", line 39, in callback
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:     discord.callback()
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:   File "/var/www/Portfolio/Flask-Discord/flask_discord/client.py", line 160, in callback
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:     return jwt.decode(state, current_app.config["SECRET_KEY"], algorithms="HS256")
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:   File "/var/www/Portfolio/env3/lib/python3.6/site-packages/jwt/api_jwt.py", line 119, in decode
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:     decoded = self.decode_complete(jwt, key, algorithms, options, **kwargs)
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:   File "/var/www/Portfolio/env3/lib/python3.6/site-packages/jwt/api_jwt.py", line 95, in decode_complete
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:     **kwargs,
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:   File "/var/www/Portfolio/env3/lib/python3.6/site-packages/jwt/api_jws.py", line 146, in decode_complete
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:     payload, signing_input, header, signature = self._load(jwt)
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:   File "/var/www/Portfolio/env3/lib/python3.6/site-packages/jwt/api_jws.py", line 190, in _load
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]:     raise DecodeError("Not enough segments") from err
Aug 14 12:28:42 caddy-ubuntu-s-1vcpu-1gb-fra1-01 gunicorn[7870]: jwt.exceptions.DecodeError: Not enough segments

Server on Production
Worked on localhost

There's a reverse proxy by caddy but that's not the issue, I hope at least its not

altab.dev {
        reverse_proxy 0.0.0.0:5000
}

Using a Forked Version of Flask-Discord (Slightly modified version, no big deal, it didn't work when I try the original version aswell)

KeyError: 'DISCORD_CLIENT_ID'

  File "c:\Users\Luite\Documents\PixelBot_dev\site\app.py", line 7, in <module>
    discord = DiscordOAuth2Session(app)
  File "C:\Users\Luite\AppData\Local\Programs\Python\Python39\lib\site-packages\flask_discord\_http.py", line 42, in __init__
    self.init_app(app)
  File "C:\Users\Luite\AppData\Local\Programs\Python\Python39\lib\site-packages\flask_discord\_http.py", line 54, in init_app
    self.client_id = self.client_id or app.config["DISCORD_CLIENT_ID"]
KeyError: 'DISCORD_CLIENT_ID'``` any idea?

Provide support for bot resources API

This will add API for resources which aren't provided under OAuth2 and require bot token as an authorization to make request. This means that it is similar to as what discord.py provides you.

Error on request with parameter

i try to get a guild member, without limit parameter i get only 1 member
discord.bot_request("/guilds/{GUILDID}/members",data=dict(limit=100))
i get error simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Can only authenticate my account

I can authenticate on my website. It works exactly as expected, I can login/logout, get my username, avatar, guilds, roles etc etc etc

I can log in on every device I have tried (desktop, laptop, phone, and over VPN)

When any other user account tries to authenticate it just fails silently. The logs show no errors, the callback gets their token but 'unauthorizederror' still gets triggered and they are sent back to the login + discord auth page.

I've even made a second account myself to test it and it won't let that account in either.

Any ideas? I have no idea what to try next.

Question

Hi, I am again with a stupid question)
How can I correctly and beautifully check which guilds
the user bot is an administrator
I would be grateful if you give advice on how to do it beautifully and quickly)

jwt.exceptions.DecodeError: Not enough segments

Traceback (most recent call last):
File "/home/container/.local/lib/python3.8/site-packages/jwt/api_jws.py", line 190, 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/container/.local/lib/python3.8/site-packages/flask/app.py", line 2073, in wsgi_app
response = self.full_dispatch_request()
File "/home/container/.local/lib/python3.8/site-packages/flask/app.py", line 1518, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/container/.local/lib/python3.8/site-packages/flask/app.py", line 1516, in full_dispatch_request
rv = self.dispatch_request()
File "/home/container/.local/lib/python3.8/site-packages/flask/app.py", line 1502, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "./site/fdpy.py", line 63, in callbackk
discord.callback()
File "/home/container/.local/lib/python3.8/site-packages/flask_discord/client.py", line 160, in callback
return jwt.decode(state, current_app.config["SECRET_KEY"], algorithms="HS256")
File "/home/container/.local/lib/python3.8/site-packages/jwt/api_jwt.py", line 119, in decode
decoded = self.decode_complete(jwt, key, algorithms, options, **kwargs)
File "/home/container/.local/lib/python3.8/site-packages/jwt/api_jwt.py", line 90, in decode_complete
decoded = api_jws.decode_complete(
File "/home/container/.local/lib/python3.8/site-packages/jwt/api_jws.py", line 149, in decode_complete
payload, signing_input, header, signature = self._load(jwt)
File "/home/container/.local/lib/python3.8/site-packages/jwt/api_jws.py", line 193, in _load
raise DecodeError("Not enough segments") from err
jwt.exceptions.DecodeError: Not enough segments

Possible to save / restore auth in browser cookie?

I'm trying to figure out just how to save / restore the OATH2 data in a browser cookie so that the user isn't prompted to re-authenticate every time they come back to my site.

What's the best way to do that?

[Question] Manage sessions opened

Is it possible to get the currently active sessions? My intention is to manage who is currently logged in and force a specific user, for example, to logoff whenever I want

(invalid_request) Invalid "code" in request.

Hi there,

I currently have an application running with Flask-Discord, but when users try to log in they sometimes get stuck at /callback with (invalid_request) Invalid "code" in request. or Not enough segments. Is there any way to fix this? Please let me know!

Thanks,
Robert S.

Add guild object

Currently, the guilds object exists, but the guild object does not exist, so it is not possible to get a lot of information, such as the number of server personnel. I think you need to add guild object.

No handle for users with no profile picutre

Exactly as explained; here's an example traceback

  File "/home/admins/.local/lib/python3.6/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/admins/.local/lib/python3.6/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/admins/.local/lib/python3.6/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/admins/.local/lib/python3.6/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/home/admins/.local/lib/python3.6/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/admins/.local/lib/python3.6/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/admins/.local/lib/python3.6/site-packages/flask_discord/utils.py", line 22, in wrapper
    return view(*args, **kwargs)
  File "website.py", line 121, in data
    return render_template("data.html", avatar_url=str(user.avatar_url)+"?size=512", user=user, guilds=guilds_data, num_guilds=len(guilds_data), guild_settings=guild_settings)
  File "/home/admins/.local/lib/python3.6/site-packages/flask_discord/models/user.py", line 106, in avatar_url
    if self.is_avatar_animated else configs.DISCORD_IMAGE_FORMAT
  File "/home/admins/.local/lib/python3.6/site-packages/flask_discord/models/user.py", line 113, in is_avatar_animated
    return self.avatar_hash.startswith("a_")
AttributeError: 'NoneType' object has no attribute 'startswith'```

Feature: list roles for guilds

discord.fetch_guilds() returns a Guild object.
It would be convenient if this Guild object has the list of roles associated to the user for this Guild.
It would allow us to manage specific permissions on the flask app.

Add support for ratelimits.

When ratelimited, .fetch_... seems to raise TypeError since the payload returns appears like:

{'global': False, 'message': 'You are being rate limited.', 'retry_after': 137}

#7

Question

Hello, please answer on my question..
Can i use your library in Django?If true, please show me how i can do it..

Invalid OAuth2 redirect_uri

My app setup is like this:

from flask import Flask, redirect, url_for, render_template, request
from flask_discord import DiscordOAuth2Session
import sqlite3
import math
app = Flask(__name__)
app.secret_key = b"YUGYT76hh6767HT76j7y6thG"
app.config["DISCORD_CLIENT_ID"] = 722199989908013057    # Discord client ID.
app.config["DISCORD_CLIENT_SECRET"] = "vC6kUTAyn_j5BNbBu3AXwkHnAa-xB32G"               
app.config["DISCORD_BOT_TOKEN"] = ""                    # Required when you want to use User.add_to_guild method.
app.config["DISCORD_REDIRECT_URI"] = "http://jackdevo.pythonanywhere.com/callback" #Won't work with localhost as Discord server cannot find i
SQLITE_DIR = "site.db"

And I have not changed the callback function. However I always get an Invalid OAuth2 redirect_uri issue when using the /login route. The URL in the browser at the time of the error shows
https://discord.com/oauth2/authorize?response_type=code&client_id=722199989908013057&redirect_uri=http%3A%2F%2Fjackdevo.pythonanywhere.com%2Fcallback&scope=identify+email+guilds+guilds.join&state=PdYUUyKlEcZEjvF7oC1uIwurlALUCB

I am really confused as the app seems to be setup correctly but no matter what type of URL I use, http or https, and even without, I get an error.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.