Nhận mã thông báo làm mới api google


79

Tôi không thể nhận mã thông báo làm mới bằng mã của mình. Tôi chỉ có thể nhận được mã thông báo truy cập, loại mã thông báo, v.v., tôi đã làm theo một số hướng dẫn như access_type=offlinenhập URL đăng nhập của mình:

echo "<a href='https://accounts.google.com/o/oauth2/auth?" 
    . "access_type=offline&client_id=123345555.apps.googleusercontent.com& "
    . "scope=https://www.googleapis.com/auth/calendar+https://www.googleapis.com/auth/plus.me&response_type=code& "
    . "redirect_uri=http://www.sample.com/sample.php&state=/profile'>Google</a>";

và các lĩnh vực của tôi trong việc nhận mã thông báo truy cập:

$fields=array(
    'code'=>  urlencode($authcode),
    'client_id'=> urlencode($clientid),
    'client_secret'=> urlencode($clientsecret),
    'redirect_uri'=> urlencode($redirecturi),
    'grant_type'=> 'authorization_code',
);

nhưng tôi không thể nhận refresh_token , chỉ là access_token , token_type , id_tokenexpires_in .


1
/ * kiểm tra liên kết này phù hợp với tôi @Nobert giải pháp * / stackoverflow.com/questions/10827920/…
Manmeet Khurana 12/1217

Câu trả lời:


109

Tìm ra bằng cách thêm cái này vào các thông số url của bạn

Browse_prompt = force

Cập nhật:

Sử dụng access_type=offline&prompt=consentthay thế.

approval_prompt=forcekhông hoạt động nữa https://github.com/googleapis/oauth2client/issues/453


12
Tại sao nó không hoạt động với Tự động? tôi không muốn người dùng mỗi lần cấp quyền. Làm thế nào tôi có thể đến đây?
Harsha MV

6
Vì mã thông báo làm mới chỉ được trả lại lần đầu tiên khi cấp quyền cho ứng dụng. Sau đó, tất cả các yêu cầu với approval_prompt=autokhông có refresh_token nữa. Kiểm tra câu trả lời này cho lời giải thích chi tiết hơn stackoverflow.com/a/10857806/987864
Daan

4
Bạn cần access_type=offlinetrong mọi trường hợp khi muốn refresh_token
Daan

7
Câu trả lời đã chỉnh sửa cho nội dung nào đó đang hoạt động vì câu trả lời này đã cũ và dường như không còn hoạt động. Tôi đã dành thời gian đáng kể để thử điều này vì có nhiều nơi nói rằng hãy sử dụng phương pháp này. Cuối cùng tôi đã đọc tài liệu (mà lẽ ra tôi nên làm trước) và nó nói rằng bạn phải sử dụng prompt=consent. Tham khảo: developers.google.com/identity/protocols/...
Goblinlord

9
Cả @Daan và @Goblinlord đều đúng, tôi đã đấu tranh với điều này ngay cả khi đọc bình luận của họ. Trong thực tế, chúng tôi cần CẢ HAI , access_type=offline&prompt=consent. Nếu không thì refresh_tokensẽ không có.
Noitidart

62

Nếu tôi có thể mở rộng câu trả lời của user987361 :

Từ phần truy cập ngoại tuyến của tài liệu OAuth2.0:

Khi ứng dụng của bạn nhận được mã làm mới, điều quan trọng là phải lưu trữ mã làm mới đó để sử dụng trong tương lai. Nếu ứng dụng của bạn mất mã làm mới, ứng dụng sẽ phải nhắc lại sự đồng ý của người dùng trước khi nhận được mã làm mới khác. Nếu bạn cần nhắc lại sự đồng ý của người dùng, hãy đưa approval_prompt thông số vào yêu cầu mã ủy quyền và đặt giá trị thành force.

Vì vậy, khi bạn đã cấp quyền truy cập, các yêu cầu tiếp theo cho một grant_typecủa authorization_codesẽ không trả về refresh_token, ngay cả khi access_typeđã được đặt thành offlinetrong chuỗi truy vấn của trang đồng ý.

Như đã nêu trong phần trích dẫn ở trên, để có được một cái mới refresh_token sau khi đã nhận được một cái, bạn sẽ cần gửi lại người dùng của mình thông qua lời nhắc, bạn có thể thực hiện bằng cách đặt approval_promptthành force.

Chúc mừng,

PS Thay đổi này cũng đã được thông báo trong một bài đăng trên blog .


3
Tôi muốn nói thêm rằng bạn chỉ cần có một cái mới refresh token nếu bạn mất nó hoặc người dùng của bạn thu hồi quyền truy cập của bạn. Nếu không, bạn có thể tiếp tục sử dụng cùng một refresh tokenđể có được các access tokens mới .
jeteon

1
Tôi có một CMS nơi những người dùng khác nhau sử dụng các tài khoản google khác nhau để kết nối với api phân tích. Tuy nhiên, đôi khi một số người dùng có thể kết nối bằng cùng một tài khoản google của công ty, nhưng mỗi người lại muốn truy cập vào một tài khoản Analytics khác nhau. Chỉ người đầu tiên nhận được mã thông báo làm mới, trong khi tất cả những người khác không nhận được và do đó phải kết nối lại mỗi giờ. Không có cách nào để lấy mã làm mới SAME cho các lần xác thực tiếp theo thay vì chỉ access_token hết hạn trong vòng một giờ?
SsjCosty

Đúng. Cứ làm đi. Khi gửi yêu cầu, bạn sẽ nhận lại được mã thông báo truy cập và mã làm mới.
bossylobster

Tôi đã lắp bắp để có được refresh_token và bạn đã chỉ cho tôi giải pháp !!! "Vì vậy, khi bạn đã cấp quyền truy cập, các yêu cầu tiếp theo đối với loại cấp_cấp_phân_cấp sẽ không trả về mã_khoản_khoản_làm_nào, ngay cả khi loại_chính_cấp được đặt thành ngoại tuyến trong chuỗi truy vấn của trang đồng ý."
Cristiana S. Parada,

12

Đó là access_type=offlineđiều bạn muốn.

Thao tác này sẽ trả lại mã thông báo làm mới vào lần đầu tiên người dùng ủy quyền ứng dụng. Các cuộc gọi tiếp theo không buộc bạn phải phê duyệt lại ứng dụng ( approval_prompt=force).

Xem thêm chi tiết: https://developers.google.com/accounts/docs/OAuth2WebServer#offline


1
Trang được liên kết đó nói rằng ứng dụng khách Google sẽ quan tâm đến việc gia hạn mã thông báo truy cập khi nó hết hạn (mã thông báo gia hạn có lẽ nằm trong tệp XML bí mật), nhưng không hiển thị cách bạn có thể phát hiện rằng mã thông báo truy cập đã thay đổi để có thể được lưu trong ứng dụng cho lần truy cập tiếp theo. Có một cuộc gọi lại cho điều này hay một ứng dụng phải luôn kiểm tra xem mã thông báo truy cập có thay đổi trong mỗi lần truy cập từ xa mà nó thực hiện không?
Jason

10

Đây là mã hoàn chỉnh bằng PHP sử dụng SDK chính thức của Google

$client = new Google_Client();
## some need parameter
$client->setApplicationName('your application name');
$client->setClientId('****************');
$client->setClientSecret('************');
$client->setRedirectUri('http://your.website.tld/complete/url2redirect');
$client->setScopes('https://www.googleapis.com/auth/userinfo.email');
## these two lines is important to get refresh token from google api
$client->setAccessType('offline');
$client->setApprovalPrompt('force'); # this line is important when you revoke permission from your app, it will prompt google approval dialogue box forcefully to user to grant offline access

8

Đối với ứng dụng của chúng tôi, chúng tôi phải sử dụng cả hai thông số này access_type=offline&prompt=consent. approval_prompt=force không làm việc cho chúng tôi


1
Cảm ơn Ricky, đây là những gì đã làm việc với tôi. Tôi nghĩ rằng các câu trả lời cũ hơn, gợi ý approval_prompt=force, có thể đúng vào thời điểm đó, nhưng không còn hiệu quả nữa. Có một số cuộc thảo luận ở đây: github.com/google/oauth2client/issues/453
Mike Morearty,

7

Xin chào, tôi đã làm theo các bước sau và tôi đã có thể nhận được mã thông báo làm mới.

Quy trình ủy quyền có hai bước.

  1. Là lấy mã ủy quyền bằng https://accounts.google.com/o/oauth2/auth?URL.

    Đối với điều đó, một yêu cầu bài viết được gửi với các thông số sau. 'scope=' + SCOPE + '&client_id=' + CLIENTID + '&redirect_uri=' + REDIRECT + '&response_type=' + TYPE + '&access_type=offline'Cung cấp ở trên sẽ nhận được mã ủy quyền.

  2. Truy xuất AcessToken và RefreshToken bằng https://accounts.google.com/o/oauth2/token?URL. Đối với điều đó, một yêu cầu bài viết được gửi với các thông số sau.

    "code": code, "client_id": CID, "client_secret": CSECRET, "redirect_uri": REDIRECT, "Grant_type": "Authority_code",

Vì vậy, trong lần thử đầu tiên khi bạn cấp quyền, bạn sẽ có thể nhận được mã thông báo Làm mới. Các lần thử tiếp theo sẽ không cung cấp mã làm mới. Nếu bạn muốn mã thông báo một lần nữa, hãy thu hồi quyền truy cập trong ứng dụng của bạn.

Hy vọng điều này sẽ giúp ai đó cổ vũ :)


4

OAuth có hai kịch bản ở chế độ thực. Kiểu truy cập thông thường và mặc định được gọi là trực tuyến. Trong một số trường hợp, ứng dụng của bạn có thể cần truy cập API Google khi người dùng không có mặt , Đó là các tình huống ngoại tuyến. mã làm mới nhận được trong các tình huống ngoại tuyến trong lần trao đổi mã ủy quyền đầu tiên.

Vì vậy, bạn có thể nhận được referenceh_token là một số kịch bản, không phải tất cả.

bạn có thể có nội dung trong https://developers.google.com/identity/protocols/OAuth2WebServer#offline .



0

Đối với những người sử dụng Thư viện ứng dụng API của Google cho PHP và tìm kiếm quyền truy cập ngoại tuyến và mã làm mới, hãy cẩn thận vào thời điểm viết bài này, tài liệu đang hiển thị các ví dụ không chính xác.

hiện nó đang hiển thị:

$client = new Google_Client();
$client->setAuthConfig('client_secret.json');
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
// offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType('offline');
// Using "consent" ensures that your application always receives a refresh token.
// If you are not using offline access, you can omit this.
$client->setApprovalPrompt("consent");
$client->setIncludeGrantedScopes(true);   // incremental auth

nguồn: https://developers.google.com/identity/protocols/OAuth2WebServer#offline

Tất cả những thứ này đều hoạt động tốt - ngoại trừ MỘT tác phẩm

$client->setApprovalPrompt("consent");

Sau một chút suy luận, tôi đã thay đổi dòng này thành dòng sau và MỌI THỨ ĐÃ LÀM VIỆC

$client->setPrompt("consent");

Nó có ý nghĩa vì sử dụng các yêu cầu HTTP, nó đã được thay đổi từ accept_prompt = force thành prompt = agree . Vì vậy, việc thay đổi phương thức setter từ setApprovalPrompt thành setPrompt tuân theo quy ước tự nhiên - NHƯNG KHÔNG CÓ TRONG DOCS !!! Điều đó tôi đã tìm thấy ít nhất.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.