2015-05-08 28 views
5

Tôi đang phạm vi chính xác để truy cập ngoại tuyến và đang lưu trữ điều đó. Cứ sau 60 phút, khi cần, tôi lấy một access_token mới. Mã đã không thay đổi, nhưng những gì là lẻ là khi ông lần đầu tiên đi qua ủy quyền.Mã thông báo truy cập và mã thông báo Làm mới cấp khoản trợ cấp không hợp lệ trong Google Plus bằng Python?

client_id  ="xxxxx.apps.googleusercontent.com" 
client_secret ="xxxxxxxxxxxxxxxxxxxx" 
refresh_token ="xxxxxxxxxxxxxxxxxxx" 
response  = oauth2a.RefreshToken(client_id,client_secret,refresh_token) 

def RefreshToken(client_id, client_secret, refresh_token): 
    params = {} 
    params['client_id'] = client_id 
    params['client_secret'] = client_secret 
    params['refresh_token'] = refresh_token 
    params['grant_type'] = 'refresh_token' 
    request_url = AccountsUrl('o/oauth2/token') 

    response = urllib.urlopen(request_url, urllib.urlencode(params)).read() 
    return json.loads(response) 

Phản hồi luôn {u'error ': u'invalid_grant'}. Tôi đã cố gắng này trên ba máy khác nhau, và cũng có được HTTPError: Lỗi HTTP 400: Bad Request

cảm ơn

Trả lời

10

lỗi Invalid_grant có hai nguyên nhân phổ biến.

  1. Đồng hồ máy chủ của bạn không đồng bộ với NTP. (Giải pháp: kiểm tra thời gian máy chủ nếu không sửa chữa được.)
  2. Đã vượt quá giới hạn mã thông báo làm mới. (Giải pháp: Không có gì bạn có thể làm họ không thể có thêm thẻ làm mới đang sử dụng) Ứng dụng có thể yêu cầu nhiều mã thông báo làm mới. Ví dụ, điều này rất hữu ích trong các tình huống mà người dùng muốn cài đặt một ứng dụng trên nhiều máy. Trong trường hợp này, yêu cầu hai mã thông báo làm mới, một mã cho mỗi lần cài đặt. Khi số mã thông báo làm mới vượt quá giới hạn, mã thông báo cũ trở nên không hợp lệ. Nếu ứng dụng cố gắng sử dụng mã thông báo làm mới không hợp lệ, phản hồi lỗi invalid_grant sẽ được trả lại. Giới hạn cho mỗi cặp máy khách OAuth 2.0 duy nhất và 25 mã thông báo làm mới (lưu ý rằng giới hạn này có thể thay đổi). Nếu ứng dụng tiếp tục yêu cầu mã thông báo làm mới cho cùng một cặp Khách hàng/Tài khoản, khi mã thông báo thứ 26 được phát hành, mã thông báo làm mới thứ 1 đã được phát hành trước đó sẽ trở thành không hợp lệ. Mã thông báo làm mới được yêu cầu thứ 27 sẽ làm mất hiệu lực mã thông báo được phát hành lần thứ 2 và cứ như vậy.
1

Bạn có thể muốn thử áp dụng cách tiếp cận được sử dụng trong mẫu auth Google+ Python Hybrid và cho phép thư viện quản lý mã thông báo OAuth 2. Một ví dụ đầy đủ ở đây:

https://developers.google.com/+/quickstart/python

Trong mẫu đó, trao đổi mã được thực hiện sử dụng thư viện của Google và các thông tin được lưu trữ trong một phiên cơ bản về thành công (bạn nên sử dụng một DB trong thực tế):

# Retrieve authorization code from POST data 
code = request.data 

try: 
    # Upgrade the authorization code into a credentials object 
    oauth_flow = flow_from_clientsecrets('client_secrets.json', scope='') 
    oauth_flow.redirect_uri = 'postmessage' 
    credentials = oauth_flow.step2_exchange(code) 
except FlowExchangeError: 
    response = make_response(
    json.dumps('Failed to upgrade the authorization code.'), 401) 
    response.headers['Content-Type'] = 'application/json' 
    return response 

#... other code ... 
session['credentials'] = credentials 

Sau đó, bạn có thể truy xuất thông tin đăng nhập (từ phiên hoặc db) và thư viện Python thực hiện phần còn lại.

"""Get list of people user has shared with this app.""" 
credentials = session.get('credentials') 
# Only fetch a list of people for connected users. 
if credentials is None: 
    response = make_response(json.dumps('Current user not connected.'), 401) 
    response.headers['Content-Type'] = 'application/json' 
    return response 
try: 
    # Create a new authorized API client. 
    http = httplib2.Http() 
    http = credentials.authorize(http) 
    # Get a list of people that this user has shared with this app. 
    google_request = SERVICE.people().list(userId='me', collection='visible') 
    result = google_request.execute(http=http) 

    response = make_response(json.dumps(result), 200) 
    response.headers['Content-Type'] = 'application/json' 
    return response 
except AccessTokenRefreshError: 
    response = make_response(json.dumps('Failed to refresh access token.'), 500) 
    response.headers['Content-Type'] = 'application/json' 
    return response 
1

Tôi gặp sự cố tương tự (hệ điều hành windows). và tôi đã khắc phục điều đó bằng cách chỉ cập nhật đồng bộ hóa máy chủ thời gian và nó hoạt động hoàn hảo.

enter image description here

+0

Nhưng trên địa phương tôi sử dụng utc + 1 và 14:25 nhưng utc là 13:25 và tôi vẫn gặp lỗi của anh ấy. – Miguel

0

Tôi đã có một vấn đề tương tự và đã nhận được một "invalid_grant" phản ứng. Hóa ra tôi đã thực hiện cuộc gọi OAuth ban đầu với grant_type = "client_credentials" và tôi nên đã thực hiện cuộc gọi bằng cách sử dụng grant_type = "password". Muốn chia sẻ giải pháp làm việc cho tôi.

More giải thích giữa grant_types có thể được tìm thấy dưới đây

Difference between grant_type=client_credentials and grant_type=password in Authentication Flow?

0

Sau khi tìm thấy rằng chuyển hướng OAuth2 đã quay trở lại mà không có một bộ thẻ làm mới, tôi thấy sửa chữa của tôi là trong chủ đề này https://github.com/google/google-api-python-client/issues/213. Tóm tắt, thêm prompt = 'consent' vào quy trình trao đổi:

flow.params['prompt'] = 'consent' 
Các vấn đề liên quan