'401: Unauthorized when trying to fetch Discord OAuth2 access token || Python 3.10
So I came to the idea one day to make a bot dashboard (it currently includes a rickroll and a pointless button). I watched some tutorials talking about how to get the user's information from OAuth2 (So that I could show them their profile on the dashboard and their servers so that they could modify the bot).
I did all the code exactly as was shown in the tutorials (even copied and pasted once or twice) but for some reason the code would return None for everything. None for username, None for userid, None for user avatar and None for guilds. btw, anyone who wants to see for themselves, this is the website: https://catsybot.235baron.repl.co/login (this will lead you to login and then will show you a broken page)

I later on made the code print out everything to see what was wrong and so far, I can only infer from the printing results that OAuth2 for some reason is refusing to give me the access_token
the results for the printing test for thus:
None #this is the user's id
None #this is the user's avatar
None #this is the username
None #this is the user's discriminator
{'message': '404: Not Found', 'code': 0} #This sometimes shows 401: Unauthorized
None #and this is the access_token
[redacted] #supposedly the code given by OAuth2
Flask file (only part of it)
@app.route('/login', methods=['GET'])
def login():
return redirect(DiscordOauth.login_url)
# Route for dashboard
@app.route('/dashboard', methods=['GET'])
def dashboard():
code = request.args.get('code')
access_token = DiscordOauth.get_access_token(code)
user_object = DiscordOauth.get_user(access_token)
user_guild_object = DiscordOauth.get_user_current_guild(access_token)
id = user_object.get('id')
avatar = user_object.get('avatar')
username = user_object.get('username')
usertag = user_object.get('discriminator')
print(str(id))
print(str(avatar))
print(str(username))
print(str(usertag))
print(str(user_object))
print(str(access_token))
print(str(code))
return render_template('dashboard.html', render_user_avatar=f'https://cdn.discordapp.com/avatars/{id}/{avatar}.png',
render_username=f'{username}#{usertag}', render_guild=user_guild_object)
discord_oauth file (only part of it)
@staticmethod
def get_access_token(code):
#access_token_url = DiscordOauth.token_url
payload = {
'client_id': DiscordOauth.client_id,
'client_secret': DiscordOauth.client_secret,
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': DiscordOauth.redirect_uri,
'scope': DiscordOauth.scope
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
access_token = requests.post(
url=DiscordOauth.token_url,
data=payload,
headers=headers
).json()
return access_token.get('access_token')
# Get user
@staticmethod
def get_user(access_token):
url = DiscordOauth.api_endpoint+"/user/@me"
headers = {
'Authorization': 'Bearer {}'.format(access_token)
}
user_object = requests.get(url=url, headers=headers)
user_json = user_object.json()
return user_json
# Get user current guild
@staticmethod
def get_user_current_guild(access_token):
user_guild_object = requests.get(
url=f'{DiscordOauth.api_endpoint}/users/@me/guilds',
headers={'Authorization': 'Bearer %s' % access_token}
).json()
return user_guild_object
EDIT
I digged into the discord developer documentation and used the code they advised there and I got this Traceback:
Traceback (most recent call last):
File "/home/runner/catsybot/venv/lib/python3.8/site-packages/flask/app.py", line 2077, in wsgi_app
response = self.full_dispatch_request()
File "/home/runner/catsybot/venv/lib/python3.8/site-packages/flask/app.py", line 1525, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/runner/catsybot/venv/lib/python3.8/site-packages/flask/app.py", line 1523, in full_dispatch_request
rv = self.dispatch_request()
File "/home/runner/catsybot/venv/lib/python3.8/site-packages/flask/app.py", line 1509, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/home/runner/catsybot/keep_alive.py", line 22, in dashboard
access_token = DiscordOauth.get_access_token(code)
File "/home/runner/catsybot/routes/discord_oauth.py", line 32, in get_access_token
r.raise_for_status()
File "/home/runner/catsybot/venv/lib/python3.8/site-packages/requests/models.py", line 960, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://discord.com/api/v8/oauth2/token
172.18.0.1 - - [19/Apr/2022 17:59:49] "GET /dashboard?code=[redacted] HTTP/1.1" 500 -
Solution 1:[1]
As it seems, my problem was that I didn't realize there was a difference between a client secret and bot token.
I thought they were the same. (I am still having problems with the getting of the user data)
Solution 2:[2]
Yeah... I found the problem, took me half an hour. The problem was in get_user function instead of url = DiscordOauth.api_endpoint+"/user/@me" url there should be url = DiscordOauth.api_endpoint+"/users/@me" not user but users
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | 235baron |
| Solution 2 | Koll |
