从URL响应中获取auth代码 - Python

时间:2016-03-16 20:24:28

标签: python http url post python-requests

我正在使用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来避免繁琐的过程来获取代码。我怎么能做到这一点?

1 个答案:

答案 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),并且需要正确获取请求的标头。没有标题,请求将无法正确重定向,您也不会获得代码!