401:尝试获取 Discord OAuth2 访问令牌时未经授权 || Python 3.10
401: Unauthorized when trying to fetch Discord OAuth2 access token || Python 3.10
所以有一天我萌生了制作一个机器人仪表板的想法(它目前包括一个 rickroll 和一个毫无意义的按钮)。我看了一些教程,讨论如何从 OAuth2 获取用户信息(这样我就可以在仪表板和服务器上向他们展示他们的个人资料,以便他们可以修改机器人)。
我完全按照教程中显示的方式编写了所有代码(甚至复制并粘贴了一两次),但出于某种原因,代码对所有内容都会 return None。 None 用于用户名,None 用于用户 ID,None 用于用户头像,None 用于公会。顺便说一句,任何想亲自看看的人,这是网站:https://catsybot.235baron.repl.co/login(这将引导您登录,然后会显示一个损坏的页面)
我后来让代码打印出所有内容以查看问题所在,到目前为止,我只能从打印结果推断 OAuth2 出于某种原因拒绝给我 access_token
打印测试结果如下:
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 文件(只有一部分)
@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 文件 (只有一部分)
@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
编辑
我深入研究了 discord 开发人员文档并使用了他们在那里建议的代码,我得到了这个 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 -
是啊...我找到了问题,花了我半个小时。
问题出在 get_user 函数而不是 url = DiscordOauth.api_endpoint+"/user/@me" url 应该是 url = DiscordOauth.api_endpoint+"/users/@me" 而不是 user但是 用户
看来,我的问题是我没有意识到客户端密码和机器人令牌之间存在差异。
我以为他们是一样的。 (我仍然无法获取用户数据)
所以有一天我萌生了制作一个机器人仪表板的想法(它目前包括一个 rickroll 和一个毫无意义的按钮)。我看了一些教程,讨论如何从 OAuth2 获取用户信息(这样我就可以在仪表板和服务器上向他们展示他们的个人资料,以便他们可以修改机器人)。
我完全按照教程中显示的方式编写了所有代码(甚至复制并粘贴了一两次),但出于某种原因,代码对所有内容都会 return None。 None 用于用户名,None 用于用户 ID,None 用于用户头像,None 用于公会。顺便说一句,任何想亲自看看的人,这是网站:https://catsybot.235baron.repl.co/login(这将引导您登录,然后会显示一个损坏的页面)
我后来让代码打印出所有内容以查看问题所在,到目前为止,我只能从打印结果推断 OAuth2 出于某种原因拒绝给我 access_token
打印测试结果如下:
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 文件(只有一部分)
@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 文件 (只有一部分)
@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
编辑
我深入研究了 discord 开发人员文档并使用了他们在那里建议的代码,我得到了这个 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 -
是啊...我找到了问题,花了我半个小时。 问题出在 get_user 函数而不是 url = DiscordOauth.api_endpoint+"/user/@me" url 应该是 url = DiscordOauth.api_endpoint+"/users/@me" 而不是 user但是 用户
看来,我的问题是我没有意识到客户端密码和机器人令牌之间存在差异。
我以为他们是一样的。 (我仍然无法获取用户数据)