我正在使用OneDrive Python SKD来处理OneDrive SDK的身份验证。身份验证完成如下:
import onedrivesdk
from onedrivesdk.helpers import GetAuthCodeServer
redirect_uri = "http://localhost:8080/"
client_secret = "your_app_secret"
client = onedrivesdk.get_default_client(client_id='your_client_id',
scopes=['wl.signin',
'wl.offline_access',
'onedrive.readwrite'])
auth_url = client.auth_provider.get_auth_url(redirect_uri)
#this will block until we have the code
code = GetAuthCodeServer.get_auth_code(auth_url, redirect_uri)
client.auth_provider.authenticate(code, redirect_uri, client_secret)
然而,由于我使用EC2实例来运行此身份验证,而且我不想仅仅为此使用浏览器,因此代码会无限期地阻塞。这是Microsoft的get_auth_code
:
def get_auth_code(auth_url, redirect_uri):
"""Easy way to get the auth code. Wraps up all the threading
and stuff. Does block main thread.
Args:
auth_url (str): URL of auth server
redirect_uri (str): Redirect URI, as set for the app. Should be
something like "http://localhost:8080" for this to work.
Returns:
str: A string representing the auth code, sent back by the server
"""
HOST, PORT = urlparse(redirect_uri).netloc.split(':')
PORT = int(PORT)
# Set up HTTP server and thread
code_acquired = threading.Event()
s = GetAuthCodeServer((HOST, PORT), code_acquired, GetAuthCodeRequestHandler)
th = threading.Thread(target=s.serve_forever)
th.start()
webbrowser.open(auth_url)
# At this point the browser will open and the code
# will be extracted by the server
code_acquired.wait() # First wait for the response from the auth server
code = s.auth_code
s.shutdown()
th.join()
return code
我想返回代码。以下是auth_url
的示例:
https://login.live.com/oauth20_authorize.srf?scope=wl.offline_access+onedrive.readwrite&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2F&response_type=code&client_id='your_client_id'
当我在浏览器中输入该URL时,我会收到代码:
http://localhost:8080/?code=Mb0bba7d1-adbc-9c1d-f790-3709cd0b9f16
所以我想通过使用requests来避免繁琐的过程来获取代码。我怎么能做到这一点?
答案 0 :(得分:1)
我知道这是一个老问题,但是我一直在同一个问题中挣扎-我想使用请求库获取代码。我设法做到了这一点,但是我怀疑这不是一个可持续的解决方案。希望阅读完我的解决方案后,您将更好地了解身份验证的工作原理,并且可以找到一种改进的解决方案。
我有一个带有MySQL数据库的Python Flask应用。有时,我想创建数据库的备份并将备份文件发送到我的OneDrive,而且我想在Flask应用程序中触发此过程。
首先,我在Microsoft Application Registration Portal注册了我的应用,并添加了一个带有重定向URL http://localhost:8080/signin-microsoft的新平台 Web 。我授予了应用程序读写权限,并存储了应用程序ID(client_id
)和应用程序密钥(client_secret
)。
第二,我向Flask应用添加了一条新路线。请注意,我的Flask应用正在localhost:8080上运行。
@app.route("/signin-microsoft", methods=['GET'])
def get_code():
return 'Yadda'
第三,我将浏览器创建的HTTP请求标头复制到我的requests.get
调用中。也就是说,我打开了Chrome,将auth_url
粘贴到地址栏,按Enter,检查请求标头并将其内容复制到我的代码中。
r = requests.get(auth_url,
headers = {"Host" : "login.live.com",
"Connection" : "keep-alive",
"Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"Accept-Encoding" : "gzip, deflate, br",
"Upgrade-Insecure-Requests" : "1",
"Accept-Language" : "fi-FI,fi;q=0.9,en-US;q=0.8,en;q=0.7",
"User-agent" : "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
"Cookie": (SUPER LONG WONT PASTE HERE)})
第四,我从重定向请求的网址中解析了代码。
re_url = r.url
code = re_url.split('code=')[-1]
这是最终代码:
redirect_uri = 'http://localhost:8080/signin-microsoft'
client_secret = CLIENT_SECRET
client_id = CLIENT_ID
api_base_url='https://api.onedrive.com/v1.0/'
scopes=['wl.signin', 'wl.offline_access', 'onedrive.readwrite']
http_provider = onedrivesdk.HttpProvider()
auth_provider = onedrivesdk.AuthProvider(
http_provider = http_provider, client_id=client_id, scopes=scopes)
client = onedrivesdk.OneDriveClient(api_base_url, auth_provider, http_provider)
auth_url = client.auth_provider.get_auth_url(redirect_uri)
r = requests.get(auth_url,
headers = {"Host" : "login.live.com",
"Connection" : "keep-alive",
"Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"Accept-Encoding" : "gzip, deflate, br",
"Upgrade-Insecure-Requests" : "1",
"Accept-Language" : "fi-FI,fi;q=0.9,en-US;q=0.8,en;q=0.7",
"User-agent" : "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36",
"Cookie": (SUPER LOOONG)})
re_url = r.url
code = re_url.split('code=')[-1]
client.auth_provider.authenticate(code, redirect_uri, client_secret)
我认为这里有两个要点:您需要一个侦听重定向uri的HTTP服务器(在Microsoft的示例中,他们使用http.server
的HTTPServer),并且需要正确获取请求的标头。没有标题,请求将无法正确重定向,您也不会获得代码!