Tôi tự hỏi về cách tốt nhất/dễ nhất để xác thực người dùng cho API dữ liệu của Google trong ứng dụng dành cho máy tính để bàn.API dữ liệu của Google: cách xác thực cho ứng dụng dành cho máy tính để bàn
Tôi đọc qua số docs và có vẻ như các tùy chọn của tôi là ClientLogin hoặc OAuth.
Đối với ClientLogin, có vẻ như tôi phải triển khai giao diện người dùng cho đăng nhập/mật khẩu (và những thứ liên quan như lưu địa điểm này ở đâu đó, v.v.). Tôi thực sự tự hỏi nếu có một số hỗ trợ nhiều hơn có thể bật lên một số màn hình đăng nhập/mật khẩu mặc định và sử dụng keychain hệ điều hành để lưu trữ mật khẩu, vv Tôi tự hỏi tại sao hỗ trợ như vậy là không có? Đó không phải là thủ tục tiêu chuẩn sao? Bằng cách để việc thực hiện đó cho dev (vâng, khả năng để việc đó liên quan đến dev là tốt), tôi đoán rằng nhiều người đã đưa ra các giải pháp rất xấu ở đây (khi họ chỉ muốn hack cùng một tập lệnh nhỏ)).
OAuth có vẻ là giải pháp tốt hơn. Tuy nhiên, dường như có một số mã bị thiếu và/hoặc hầu hết mã tôi tìm thấy dường như chỉ liên quan đến các ứng dụng web. Esp., Tôi đã làm theo tài liệu và có here. Đã có trong phần giới thiệu, nó nói về ứng dụng web. Sau đó, sau này, tôi cần phải xác định một URL gọi lại mà không có ý nghĩa cho một ứng dụng máy tính để bàn. Ngoài ra tôi tự hỏi những gì người tiêu dùng chính/bí mật tôi nên đặt như vậy cũng không thực sự có ý nghĩa cho một ứng dụng máy tính để bàn (đặc biệt là không cho một nguồn mở). Tôi đã tìm kiếm một chút và được cho là here (on SO) rằng tôi nên sử dụng "ẩn danh"/"ẩn danh" làm khóa/bí mật của người tiêu dùng; nhưng nó nói ở đâu trong tài liệu của Google? Và làm cách nào để nhận mã thông báo sau khi người dùng đã tự xác thực?
Có một số mã mẫu không? (Không phải với một tên người dùng mã hóa cứng/mật khẩu nhưng với một phương thức xác thực đầy đủ thể tái sử dụng.)
Cảm ơn, Albert
Mã của tôi cho đến nay:
import gdata.gauth
import gdata.contacts.client
CONSUMER_KEY = 'anonymous'
CONSUMER_SECRET = 'anonymous'
SCOPES = [ "https://www.google.com/m8/feeds/" ] # contacts
client = gdata.contacts.client.ContactsClient(source='Test app')
import BaseHTTPServer
import SocketServer
Handler = BaseHTTPServer.BaseHTTPRequestHandler
httpd = BaseHTTPServer.HTTPServer(("", 0), Handler)
_,port = httpd.server_address
oauth_callback_url = 'http://localhost:%d/get_access_token' % port
request_token = client.GetOAuthToken(
SCOPES, oauth_callback_url, CONSUMER_KEY, consumer_secret=CONSUMER_SECRET)
loginurl = request_token.generate_authorization_url(google_apps_domain=None)
loginurl = str(loginurl)
import webbrowser
webbrowser.open(loginurl)
Tuy nhiên, điều này không làm việc . Tôi gặp lỗi này:
Sorry, you've reached a login page for a domain that isn't using Google Apps. Please check the web address and try again.
Tôi không hiểu điều đó. Tất nhiên tôi không sử dụng Google Apps.
Ah, lỗi đó xuất phát từ google_apps_domain=None
trong generate_authorization_url
. Rời khỏi đó đi (tức là chỉ loginurl = request_token.generate_authorization_url()
và nó hoạt động cho đến nay
mã hiện tại của tôi:.
import gdata.gauth
import gdata.contacts.client
CONSUMER_KEY = 'anonymous'
CONSUMER_SECRET = 'anonymous'
SCOPES = [ "https://www.google.com/m8/feeds/" ] # contacts
client = gdata.contacts.client.ContactsClient(source='Test app')
import BaseHTTPServer
import SocketServer
httpd_access_token_callback = None
class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
if self.path.startswith("/get_access_token?"):
global httpd_access_token_callback
httpd_access_token_callback = self.path
self.send_response(200)
def log_message(self, format, *args): pass
httpd = BaseHTTPServer.HTTPServer(("", 0), Handler)
_,port = httpd.server_address
oauth_callback_url = 'http://localhost:%d/get_access_token' % port
request_token = client.GetOAuthToken(
SCOPES, oauth_callback_url, CONSUMER_KEY, consumer_secret=CONSUMER_SECRET)
loginurl = request_token.generate_authorization_url()
loginurl = str(loginurl)
print "opening oauth login page ..."
import webbrowser; webbrowser.open(loginurl)
print "waiting for redirect callback ..."
while httpd_access_token_callback == None:
httpd.handle_request()
print "done"
request_token = gdata.gauth.AuthorizeRequestToken(request_token, httpd_access_token_callback)
# Upgrade the token and save in the user's datastore
access_token = client.GetAccessToken(request_token)
client.auth_token = access_token
Điều đó sẽ mở trang Google OAuth với gợi ý ở phía dưới:
This website has not registered with Google to establish a secure connection for authorization requests. We recommend that you deny access unless you trust the website.
Nó Tuy nhiên, khi tôi cố gắng truy cập vào các liên hệ (nghĩa là chỉ một số client.GetContacts()
), tôi nhận được lỗi này:
gdata.client.Unauthorized: Unauthorized - Server responded with: 401, <HTML>
<HEAD>
<TITLE>Token invalid - AuthSub token has wrong scope</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Token invalid - AuthSub token has wrong scope</H1>
<H2>Error 401</H2>
</BODY>
</HTML>
Ok, có vẻ như tôi thực sự đã đặt sai phạm vi. Khi tôi sử dụng http
thay vì https
(ví dụ: SCOPES = [ "http://www.google.com/m8/feeds/" ]
), nó hoạt động.
Nhưng tôi thực sự muốn sử dụng https. Tôi tự hỏi làm thế nào tôi có thể làm điều đó.
Ngoài ra, một vấn đề khác với giải pháp này:
Trong danh sách truy cập được phép vào tài khoản Google của tôi, bây giờ tôi có một loạt các mục localhost như:
localhost:58630 — Google Contacts [ Revoke Access ]
localhost:58559 — Google Contacts [ Revoke Access ]
localhost:58815 — Google Contacts [ Revoke Access ]
localhost:59174 — Google Contacts [ Revoke Access ]
localhost:58514 — Google Contacts [ Revoke Access ]
localhost:58533 — Google Contacts [ Revoke Access ]
localhost:58790 — Google Contacts [ Revoke Access ]
localhost:59012 — Google Contacts [ Revoke Access ]
localhost:59191 — Google Contacts [ Revoke Access ]
Tôi tự hỏi như thế nào Tôi có thể tránh được điều đó.
Khi tôi sử dụng xoauth_displayname
, tên này sẽ hiển thị tên đó thay vào đó nhưng vẫn tạo nhiều mục nhập (có thể do URL hầu như vẫn khác nhau (vì cổng) mỗi lần). Làm thế nào tôi có thể tránh điều đó?
Mã hiện tại của tôi hiện đang ở Github.
Tôi cũng tự hỏi, ở đâu, như thế nào và trong bao lâu tôi nên lưu trữ access token và/hoặc yêu cầu thẻ để người dùng không yêu cầu luôn một lần nữa và một lần nữa mỗi lần khi người dùng khởi động ứng dụng.
Việc ủy quyền của người sử dụng - cách chính xác sẽ nhìn đó như? Tôi có mở một trình duyệt web bên ngoài và bằng cách nào đó kiểm tra lại thường xuyên nếu mã thông báo được ủy quyền không? Trong mã ví dụ, tôi không thực sự thấy vị trí của trình duyệt web được mở. – Albert
Ngoài ra, có vẻ như gdata lib đã đi kèm với các hàm cho OAuth. Vì vậy, tôi đoán tôi không cần một lib cho điều đó? Hoặc python-oauth2 cung cấp gì ngoài những gì tôi đã có với gdata? – Albert
OAuth ba bên hoạt động như sau: 1. Bạn yêu cầu mã thông báo và bí mật mã thông báo từ nhà cung cấp (Google) 2.Bạn mở một webbrowser cho người dùng và đưa anh ta đến URL ủy quyền của nhà cung cấp nơi người dùng có thể xác nhận họ muốn cung cấp cho bạn quyền truy cập và bạn lấy lại mã xác minh. Trang web của nhà cung cấp có thể gọi lại cho bạn qua một URL cung cấp trình xác minh hoặc cung cấp cho người dùng mã xác minh mà bạn cần. 3. với mã thông báo ban đầu và người xác minh bạn có thể có được mã thông báo cuối cùng của bạn từ nhà cung cấp. – ldx