我一直在研究一個使用OAuth2來識別用戶的python應用程序。我似乎成功實現了OAuth2隱式授權(通常用於已安裝應用程序和用戶代理應用程序)的工作流程,但在接收令牌的最後一步,似乎出現了問題。用PyQt4/5隱式OAuth2授權
每當用戶需要認證時,就會產生一個顯示登錄頁面的PyQt QWebView窗口(基於webkit)。在用戶登錄並允許我的應用程序使用範圍權限後,OAuth2服務器將重定向到預先指定的redirect_uri。
問題是,當使用QWebView瀏覽器時,通常出現在#後的標記字符串似乎已從URL中刪除:QWebView返回的URL僅爲基本的redirect_uri。
如果我複製粘貼OAuth授權URL並按照這些相同的步驟在Chrome或Firefox等普通Web瀏覽器中登錄和授權,我確實會看到包含令牌字符串的redirect_uri,所以問題確實如此不在OAuth2過程中,但在執行過程中必須出錯。
這是QWebView或webkit實現的固有行爲嗎?我錯誤地讀出了QUrl?
爲了完整起見,這裏是我的代碼:
產生用於開放科學框架中的OAuth2網址osf.py模塊。
# Import basics
import sys
import os
# Module for easy OAuth2 usage, based on the requests library,
# which is the easiest way to perform HTTP requests.
# OAuth2Session object
from requests_oauthlib import OAuth2Session
# Mobile application client that does not need a client_secret
from oauthlib.oauth2 import MobileApplicationClient
#%%----------- Main configuration settings ----------------
client_id = "cbc4c47b711a4feab974223b255c81c1"
# TESTED, just redirecting to Google works in normal browsers
# the token string appears in the url of the address bar
redirect_uri = "https://google.nl"
# Generate correct URLs
base_url = "https://test-accounts.osf.io/oauth2/"
auth_url = base_url + "authorize"
token_url = base_url + "token"
#%%--------------------------------------------------------
mobile_app_client = MobileApplicationClient(client_id)
# Create an OAuth2 session for the OSF
osf_auth = OAuth2Session(
client_id,
mobile_app_client,
scope="osf.full_write",
redirect_uri=redirect_uri,
)
def get_authorization_url():
""" Generate the URL with which one can authenticate at the OSF and allow
OpenSesame access to his or her account."""
return osf_auth.authorization_url(auth_url)
def parse_token_from_url(url):
token = osf_auth.token_from_fragment(url)
if token:
return token
else:
return osf_auth.fetch_token(url)
主程序,打開了登錄屏幕QWebView瀏覽器窗口
# Oauth2 connection to OSF
import off
import sys
from PyQt4 import QtGui, QtCore, QtWebKit
class LoginWindow(QtWebKit.QWebView):
""" A Login window for the OSF """
def __init__(self):
super(LoginWindow, self).__init__()
self.state = None
self.urlChanged.connect(self.check_URL)
def set_state(self,state):
self.state = state
def check_URL(self, url):
#url is a QUrl object, covert it to string for easier usage
url_string = url.toEncoded()
print(url_string)
if url.hasFragment():
print("URL CHANGED: On token page: {}".format(url))
self.token = osf.parse_token_from_url(url_string)
print(self.token)
elif not osf.base_url in url_string:
print("URL CHANGED: Unexpected url")
if __name__ == "__main__":
""" Test if user can connect to OSF. Opens up a browser window in the form
of a QWebView window to do so."""
# Import QT libraries
app = QtGui.QApplication(sys.argv)
browser = LoginWindow()
auth_url, state = osf.get_authorization_url()
print("Generated authorization url: {}".format(auth_url))
browser_url = QtCore.QUrl.fromEncoded(auth_url)
browser.load(browser_url)
browser.set_state(state)
browser.show()
exitcode = app.exec_()
print("App exiting with code {}".format(exitcode))
sys.exit(exitcode)
基本上,這是由QWebView的URL_CHANGED事件決不會包含OAuth令牌片段提供給check_URL功能的網址當從OAuth服務器回來時,無論我用於redirect_uri(在本例中,爲簡單起見,我都簡單地重定向到谷歌)。
任何人都可以請幫助我嗎?我已經用盡了我在哪裏尋找解決這個問題的選擇。