2012-12-08 34 views
14

Tôi đang phát triển một ứng dụng truy cập API Google (bắt đầu bằng API lịch) bằng OAuth2 và thư viện ứng dụng khách Google (trên Appengine và GWT BTW).Cách nhận mã thông báo ngoại tuyến và mã thông báo làm mới cũng như tự động làm mới quyền truy cập vào API Google

Tôi đã triển khai servlet OAuth2Call quay lại của mình, mở rộng Google AbstractAppEngineAuthorizationCodeCallbackServlet.

Tôi có nó làm việc, tôi được tiếp cận và có thể nhìn vào lịch vv, nhưng có hai vấn đề:

1) Tôi không nhận được một mã thông báo làm mới, bất chấp yêu cầu một cách rõ ràng truy cập ẩn:

public static GoogleAuthorizationCodeFlow newFlow(String scope) throws IOException { 
    GoogleAuthorizationCodeFlow.Builder builder = new GoogleAuthorizationCodeFlow.Builder(
      HTTP_TRANSPORT, 
      JSON_FACTORY, 
      getClientSecrets(), 
      Collections.singleton(scope)); 

    builder.setCredentialStore(new AppEngineCredentialStore()).setAccessType("offline"); 

    return builder.build(); 
} 

2) Tôi không thể xem cách đặt chức năng làm mới tự động. Những trang này mô tả các phương pháp:

Nhưng tôi không thể nhìn thấy nơi để thêm người nghe làm mới. Không có phương pháp như vậy trong lớp GoogleAuthorizationCodeFlow.Builder, không giống như các Credential.Builder lớp

EDIT Sau khi gỡ lỗi mã hơn, khi các chứng chỉ trở lại (trong phương pháp onSuccess()) nó dường như có một bộ RefreshListener đã ..... vì vậy có lẽ đó là của họ theo mặc định, và vấn đề duy nhất của tôi là tôi không nhận được một refresh_token, mặc dù yêu cầu cho nó.

Có thể bạn cũng cần xem lại cài đặt trong Bảng điều khiển API của Google?

Trả lời

16

Một điều bạn nên cẩn thận: mã thông báo làm mới được trả về (ngoài mã thông báo truy cập) chỉ khi người dùng cho phép rõ ràng cho các phạm vi được yêu cầu. Về cơ bản, khi trang phê duyệt được hiển thị. Tất cả các luồng tiếp theo sẽ chỉ trả lại mã thông báo truy cập.

Bây giờ, để kiểm tra ứng dụng của bạn và đảm bảo bạn nhận được mã thông báo làm mới lần đầu tiên, bạn có thể sử dụng tham số approval_prompt = force (builder.setApprovalPrompt("force")) để đảm bảo trang phê duyệt được hiển thị trong luồng và bạn có được sự đồng ý rõ ràng từ người dùng. Sau khi bạn sắp xếp bất kỳ vấn đề nào và đảm bảo mã thông báo làm mới được lưu trữ đúng cách, bạn có thể xóa cờ đó (mặc định là auto)

Thông tin khác cũng có trong offline access section trong hướng dẫn dành cho nhà phát triển.

+0

Cảm ơn nhận xét, tôi sẽ kiểm tra theo các dòng này. Tại thời điểm này, tôi thực hiện thu hồi mã thông báo rõ ràng và sau đó yêu cầu lại và tôi luôn đi qua màn hình chấp nhận rõ ràng cho người dùng - nhưng vẫn không nhận được tệp refresh_token. –

+0

vlatko, tôi đã làm mọi thứ bạn nói * ngoại trừ * lực lượng nhắc nhở, và dường như đã sửa nó! Vì vậy, câu trả lời của bạn đã được đánh giá cao! Đây có phải là một lỗi, hoặc chỉ là một thiếu sót rõ ràng từ các tài liệu (quá rộng ...)? –

0

Tôi đã xem xét điều này và kết luận rằng access_token chỉ cần được sử dụng một lần. Đó là, mỗi lần tìm kiếm Google là một quá trình hai bước:

  1. Sử dụng refresh_token để tạo ra một access_token tạm
  2. Sử dụng access_token cho một hoặc nhiều truy vấn cần thiết cho hoạt động của bạn.

Tôi đã xem một vài bài đăng ở đây về việc đảm bảo rằng đồng hồ máy chủ được đồng bộ hóa. Nhưng điều đó có vẻ phức tạp không cần thiết.

Đối với một lời giải thích chi tiết hơn: http://www.tqis.com/eloquency/googlecalendar.htm

+0

Cảm ơn Sunny. Nhưng vấn đề là trên ủy quyền đầu tiên tôi đã nhận được AccessToken, nhưng không phải là RefreshToken, mặc dù yêu cầu nó bằng cách thiết lập AccessType để "offline". Nếu bạn sử dụng các lớp Google (một khi bạn có một RefreshToken) họ sẽ lưu trữ nó và sử dụng nó để tự động nhận được một AccessToken mới khi nó hết hạn, tất cả đều trong suốt cho bạn. –

4

Để có được refresh mã thông báo bạn phải đặt cả accessType = "ẩn" và approvalPrompt = "lực lượng".

GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, 
       JSON_FACTORY, CLIENT_ID, CLIENT_SECRET, SCOPE).setAccessType("offline").setApprovalPrompt("force").build(); 
+0

Ok, cảm ơn vì điều này! .setApprovalPrompt (..) phải là một yêu cầu tương đối mới. Tôi đã có mã của tôi làm việc khoảng một hoặc hai tháng trước mà không có tùy chọn này và nó đã cho tôi thẻ làm mới. Đột nhiên nó đã ngừng hoạt động và tôi bị bỏ lại để tự hỏi tại sao. – ThaDon

Các vấn đề liên quan