如何使用 oauth2 访问 StackExchange API?

How to use oauth2 to access StackExchange API?

我正在按照此处提到的说明进行操作:https://api.stackexchange.com/docs/authentication

但由于没有提供代码,我无法正确理解流程。

我一直在尝试使用以下两种方法完成身份验证部分,但我遇到了死胡同。

1)

import requests
from pprint import pprint

resp = requests.get('https://stackexchange.com/oauth/dialog?client_id=6667&scope=private_info&redirect_uri=https://stackexchange.com/oauth/login_success/')
pprint(vars(resp))

2)

import oauth2 as oauth
from pprint import pprint

url = 'https://www.stackexchange.com'
request_token_url = '%s/oauth/' % url
access_token_url = '%s/' % url

consumer = oauth.Consumer(key='mykey',
                          secret='mysecret')

client = oauth.Client(consumer)


response, content = client.request(request_token_url, 'GET')

print(response, content)

我不确定如何从这里前进?我需要使用返回的访问令牌并使用它来查询 API。示例代码真的很有帮助!谢谢。

编辑:这是我目前使用的代码:

from requests_oauthlib import OAuth2Session
from pprint import pprint

client_id = 'x'
client_secret = 'x'
redirect_uri = 'https://stackexchange.com/oauth/login_success'
scope = 'no_expiry'

oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scope)

pprint(vars(oauth))

authorization_url, state = oauth.authorization_url('https://stackexchange.com/oauth/dialog')

print(authorization_url)

我不必点击 authorization_url 并获取令牌,有没有一种方法可以直接在脚本本身中获取令牌?

在您使用的两种方法中,第一种是桌面应用程序的推荐方法。大概是对的。

OAuth 旨在强制用户转到特定网页并确认他们正在授予应用程序访问其数据的权限(通常通过单击按钮)。您打印的 HTTP 响应只是用户需要单击接受的网页。

要感受流程,请将第一个地址 (https://stackexchange.com/oauth/dialog?client_id=6667&scope=&redirect_uri=https://stackexchange.com/oauth/login_success/) 放在地址栏中,然后在加载的页面上单击接受。 access_token 将在 URL 之后。

如果您只是为自己申请,可以将 access_token 复制到您的 Python 脚本中。令牌将在一天后过期;如果太短,请将 no_expiry 添加到 scope 以使其永远持续下去。不要与其他任何人共享令牌,因为它可以让他们访问您帐户的详细信息!脚本的每个用户都必须生成自己的令牌。

测试 access_token 通过插入你的应用程序的 key 和你刚刚获得的 access_token 到 url: https://api.stackexchange.com/2.2/me?key=key&site=Whosebug&order=desc&sort=reputation&access_token=&filter=default

如果您需要更加自动化、集成化、用户友好的解决方案,我会查看 selenium webdriver 打开浏览器 window 并获取生成的凭据。

只是对 Marc 回答的一个小修正。如果你想让访问令牌永远持续下去,你应该添加 no_expiry 而不是 no_expire.