গুগল এপিআই ক্লায়েন্টের সাথে টোকেন কীভাবে রিফ্রেশ করবেন?


92

আমি গুগল অ্যানালিটিক্স এপিআই (ভি 3) এর সাথে ঘুরে বেড়াচ্ছি এবং প্রচুর ত্রুটির মধ্যে পড়েছি। প্রথমত, সবকিছু সঠিকভাবে সেট আপ করা হয় এবং আমার পরীক্ষার অ্যাকাউন্টের সাথে কাজ করে। কিন্তু যখন আমি অন্য প্রোফাইল আইডি (একই গুগল একাউন্ট / জিএ অ্যাকাউন্ট) থেকে ডেটা ধরতে চাই তখন আমি একটি 403 ত্রুটি পাই। আশ্চর্যের বিষয়টি হ'ল কিছু জিএ অ্যাকাউন্টের ডেটা অন্য ত্রুটিটি তৈরি করার সময় ডেটা ফেরত দেবে।

আমি টোকেনটি বাতিল করে দিয়েছি এবং আরও একবার প্রমাণীকৃত করেছি এবং এখন দেখে মনে হচ্ছে আমি আমার সমস্ত অ্যাকাউন্ট থেকে ডেটা ধরতে পারি। সমস্যা সমাধান? না. অ্যাক্সেস কীটির মেয়াদ শেষ হওয়ার সাথে সাথে আমি আবার একই সমস্যাটিতে চলে আসব।

আমি যদি জিনিসগুলি সঠিকভাবে বুঝতে পারি তবে একটি নতুন প্রমাণীকরণ টুকেন পেতে রেফ্রেশটোকন ব্যবহার করতে পারে।

সমস্যাটি হ'ল, আমি যখন দৌড়ব:

$client->refreshToken(refresh_token_key) 

নিম্নলিখিত ত্রুটি ফিরে এসেছে:

Error refreshing the OAuth2 token, message: '{ "error" : "invalid_grant" }'

আমি রিফ্রেশ টোকেন পদ্ধতির পিছনে কোডটি যাচাই করেছি এবং অনুরোধটি "apiOAuth2.php" ফাইলটিতে ফিরে পেয়েছি। সমস্ত পরামিতি সঠিকভাবে প্রেরণ করা হয়। অনুদান_প্রকারটি পদ্ধতিটির মধ্যে 'রিফ্রেশ_ টোকেন' তে শক্তভাবে কোড করা হয়েছে, তাই আমার কী সমস্যা তা বোঝা মুশকিল। প্যারামিটার অ্যারে দেখে মনে হচ্ছে:

Array ( [client_id] => *******-uqgau8uo1l96bd09eurdub26c9ftr2io.apps.googleusercontent.com [client_secret] => ******** [refresh_token] => 1\/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY [grant_type] => refresh_token )

নিম্নরূপ পদ্ধতি।

$client = new apiClient();
$client->setClientId($config['oauth2_client_id']);
$client->setClientSecret($config['oauth2_client_secret']);
$client->setRedirectUri($config['oauth2_redirect_uri']);
$client->setScopes('https://www.googleapis.com/auth/analytics.readonly');
$client->setState('offline');

$client->setAccessToken($config['token']); // The access JSON object.

$client->refreshToken($config['refreshToken']); // Will return error here

এটি কি কোনও বাগ, বা আমি কোনও কিছুকে পুরোপুরি ভুল বুঝেছি?


এটি কোনও বাগ বা অন্য কিছু কিনা তা জানেন না তবে আমি বর্তমানে একটি কাঁচা সিআরএল HTTP অনুরোধ ব্যবহার করে অ্যাক্সেস টোকনটি রিফ্রেশ করছি এবং এটি ভাল কাজ করছে।
গ্রিমো

Seorch ... আপনি এটি এক খুঁজে এখনও? একই সমস্যা এখানে।
ব্রায়ান ভ্যান্ডারবাউশ

@ গ্রেমো আপনি এখানে ব্যবহৃত কাঁচা সিআরএল HTTP অনুরোধটি ভাগ করে নিতে পারেন? সত্যিই সহায়ক হবে। ধন্যবাদ!
রৌপ্য রিঙ্গভী

উত্তর:


76

সুতরাং আমি অবশেষে এটি কীভাবে করতে পারি তা বুঝতে পেরেছি। প্রাথমিক ধারণাটি হ'ল আপনি যখন প্রথম প্রমাণীকরণ চেয়েছিলেন তখন আপনার কাছে টোকেন রয়েছে। এই প্রথম টোকনে একটি রিফ্রেশ টোকেন রয়েছে। প্রথম আসল টোকেনটি এক ঘন্টা পরে শেষ হয়। এক ঘন্টা পরে আপনাকে নতুন ব্যবহারযোগ্য টোকেন পেতে প্রথম টোকেন থেকে রিফ্রেশ টোকেন ব্যবহার করতে হবে। আপনি $client->refreshToken($refreshToken)একটি নতুন টোকেন পুনরুদ্ধার করতে ব্যবহার করুন । আমি এটিকে "টেম্প টোকন" বলব। আপনার এই টেম্প টোকেনটিও সংরক্ষণ করতে হবে কারণ এক ঘন্টা পরে এটির মেয়াদও শেষ হয়ে যায় এবং নোট করুন এটির সাথে রিফ্রেশ টোকেন যুক্ত নেই। একটি নতুন টেম্প টোকেন পেতে আপনার আগে ব্যবহৃত পদ্ধতিটি ব্যবহার করতে হবে এবং প্রথম টোকেনের রিফ্রেশ টোকেন ব্যবহার করতে হবে। আমি নীচে কোড সংযুক্ত করেছি, যা কুরুচিপূর্ণ, তবে আমি এতে নতুন ...

//pull token from database
$tokenquery="SELECT * FROM token WHERE type='original'";
$tokenresult = mysqli_query($cxn,$tokenquery);
if($tokenresult!=0)
{
    $tokenrow=mysqli_fetch_array($tokenresult);
    extract($tokenrow);
}
$time_created = json_decode($token)->created;
$t=time();
$timediff=$t-$time_created;
echo $timediff."<br>";
$refreshToken= json_decode($token)->refresh_token;


//start google client note:
$client = new Google_Client();
$client->setApplicationName('');
$client->setScopes(array());
$client->setClientId('');
$client->setClientSecret('');
$client->setRedirectUri('');
$client->setAccessType('offline');
$client->setDeveloperKey('');

//resets token if expired
if(($timediff>3600)&&($token!=''))
{
    echo $refreshToken."</br>";
    $refreshquery="SELECT * FROM token WHERE type='refresh'";
    $refreshresult = mysqli_query($cxn,$refreshquery);
    //if a refresh token is in there...
    if($refreshresult!=0)
    {
        $refreshrow=mysqli_fetch_array($refreshresult);
        extract($refreshrow);
        $refresh_created = json_decode($token)->created;
        $refreshtimediff=$t-$refresh_created;
        echo "Refresh Time Diff: ".$refreshtimediff."</br>";
        //if refresh token is expired
        if($refreshtimediff>3600)
        {
            $client->refreshToken($refreshToken);
        $newtoken=$client->getAccessToken();
        echo $newtoken."</br>";
        $tokenupdate="UPDATE token SET token='$newtoken' WHERE type='refresh'";
        mysqli_query($cxn,$tokenupdate);
        $token=$newtoken;
        echo "refreshed again";
        }
        //if the refresh token hasn't expired, set token as the refresh token
        else
        {
        $client->setAccessToken($token);
           echo "use refreshed token but not time yet";
        }
    }
    //if a refresh token isn't in there...
    else
    {
        $client->refreshToken($refreshToken);
        $newtoken=$client->getAccessToken();
        echo $newtoken."</br>";
        $tokenupdate="INSERT INTO token (type,token) VALUES ('refresh','$newtoken')";
        mysqli_query($cxn,$tokenupdate);
        $token=$newtoken;
        echo "refreshed for first time";
    }      
}

//if token is still good.
if(($timediff<3600)&&($token!=''))
{
    $client->setAccessToken($token);
}

$service = new Google_DfareportingService($client);

52
3600 সেকেন্ডের জন্য পরীক্ষা করার পরিবর্তে, আপনার $ ক্লায়েন্ট-> ব্যবহার করা উচিতঅ্যাক্সেসটোকেন এক্সপায়ার্ড ()
গৌরব গুপ্ত

4
ছোট আপডেট। সর্বশেষতম সংস্করণে, আপনি যখন রিফ্রেশ টোকেনটির অনুরোধ করবেন তখন যে নতুন অ্যাক্সেস টোকেন এখন ফিরে আসবে তা একটি নতুন রিফ্রেশ টোকন নিয়ে আসে। অতএব মূলত, আপনি পূর্ববর্তী জসন টোকেনটি প্রতিস্থাপন করতে আপডেট করা জসন টোকেন ব্যবহার করতে পারেন এবং আর প্রাথমিক আর অ্যাক্সেস টোকেন ধরে রাখার দরকার নেই। ।
স্কিডিডন

4
দ্রষ্টব্য যে $client->isAccessTokenExpired()এখনও স্থানীয়ভাবে অনুষ্ঠিত সময়গুলি কেবলমাত্র এটি দেখার জন্য টোকেনটির মেয়াদ শেষ হয়ে গেছে কিনা তা পরীক্ষা করে দেখবে। টোকেনটি এখনও মেয়াদোত্তীর্ণ হয়ে থাকতে পারে এবং স্থানীয় অ্যাপ্লিকেশন কেবল তখনই জানবে যে এটি কখন এটি ব্যবহার করার চেষ্টা করবে। এই ক্ষেত্রে এপিআই ক্লায়েন্ট একটি ব্যতিক্রম ফিরিয়ে দেবে, এবং টোকনটি স্বয়ংক্রিয়ভাবে রিফ্রেশ করবে না
জেসন

@ জেসন এখন সত্য নয় বলে আমি মনে করি। আমি নীচে রিটার্নের স্টেটমেন্টটি "isAccessTokenE Expired" পদ্ধতিতে দেখছি: রিটার্ন ($ তৈরি + ($ এটি-> টোকেন ['মেয়াদ উত্তীর্ণ_'ইন'] - 30%) <সময় ();
সুদীপ

44

রিফ্রেশ টোকনে সমস্যাটি রয়েছে:

[refresh_token] => 1\/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY

যখন কোনও স্ট্রিং যখন '/'পায় তখন json encodedএটি দিয়ে পালিয়ে যায় '\', সুতরাং আপনাকে এটি সরিয়ে ফেলতে হবে।

আপনার ক্ষেত্রে রিফ্রেশ টোকেনটি হ'ল:

1/lov250YQTMCC9LRQbE6yMv-FiX_Offo79UXimV8kvwY

আমি ধরে নিচ্ছি যে আপনি কী করেছেন তা হ'ল আপনি জসন স্ট্রিংটি মুদ্রণ করেছেন যা গুগল ফেরত পাঠিয়েছে এবং টোকনটি আপনার কোডটিতে অনুলিপি করে আটকিয়েছে কারণ আপনি যদি json_decodeতা করেন তবে এটি সঠিকভাবে আপনার '\'জন্য সরিয়ে ফেলবে !


4
আশ্চর্যজনক উল্লেখ, আমার দিন তৈরি! সময় বাঁচানো!
মিরসিয়া সান্দু

তুমি আমার দিন বাঁচিয়েছ!
ট্রুং ডাং

আমি আশা করি আমি এই 100 বার upvote করতে পারে। টোকেনটির কাজটি করার জন্য একেবারে সবকিছু চেষ্টা করার পরে বেশ কয়েক ঘন্টা "খারাপ অনুদান" বার্তাটি দেখার পরে আমি আমার কীবোর্ড দিয়ে একটি প্রাচীরের গর্ত করতে চলেছিলাম। ফ্রিকিং গুগল ম্যান, স্ল্যাশ কেন ব্যবহার করবেন, শুধু কেন?
আসকম্যান

18

টোকেন সেট করার জন্য এখানে স্নিপেট রয়েছে, তার আগে অ্যাক্সেস টাইপটি অফলাইনে সেট করা উচিত তা নিশ্চিত করুন

if (isset($_GET['code'])) {
  $client->authenticate();
  $_SESSION['access_token'] = $client->getAccessToken();
}

টোকেন রিফ্রেশ

$google_token= json_decode($_SESSION['access_token']);
$client->refreshToken($google_token->refresh_token);

এটি আপনার টোকেনকে রিফ্রেশ করবে, আপনি এটি করতে পারেন তার জন্য আপনাকে এটি সেশনে আপডেট করতে হবে

 $_SESSION['access_token']= $client->getAccessToken()

4
আপনি এই দিয়ে আমার দিনটি তৈরি করেছেন :) আপনাকে অনেক ধন্যবাদ, আমি যেহেতু অনেক বেশি সময় ব্যয় করে
চলেছি

16

অ্যাক্সেসের ধরণটি সেট করা উচিত offlinestateআপনি নিজের ব্যবহারের জন্য সেট করেছেন এমন একটি পরিবর্তনশীল, এটি API এর ব্যবহার নয়।

আপনার কাছে ক্লায়েন্ট লাইব্রেরির সর্বশেষতম সংস্করণ রয়েছে এবং তা যুক্ত করুন:

$client->setAccessType('offline');

পরামিতিগুলির ব্যাখ্যার জন্য ইউআরএল তৈরি করা দেখুন ।


ধন্যবাদ জে.কে. আমি সর্বশেষতম সংস্করণ ডাউনলোড করেছি এবং আমার অ্যাকাউন্টের জন্য অ্যাপ্লিকেশনটিতে অ্যাক্সেস প্রত্যাহার করেছি। তারপরে আমি আরও একবার অ্যাক্সেস পেয়েছি এবং অ্যাক্সেস টোকেন এবং রিফ্রেশ টোকেন সংরক্ষণ করেছি। জিনিসটি হ'ল আমাকে সর্বদা একটি রিফ্রেশ টোকেন দেওয়া হয়েছে, এমনকি যদি সেটঅ্যাক্সেসটাইপটি বাদ দেওয়া হয়। যাইহোক, আমি যখন $ ক্লায়েন্ট-> রিফ্রেশ টোকেন (রিফ্রেশ-টোকেন-কী) চালাই, তখনও আমি "অবৈধ_গ্রান্ট" ত্রুটি পাই। আমি auth-url পরীক্ষা করে দেখেছি এবং এটি "জোর করা" থেকে ডিফল্ট। যদি আমি এটিকে "অটো" তে পরিবর্তন করি এবং প্রমাণীকরণ পদ্ধতি চালাই তবে আমি ইতিমধ্যে অ্যাক্সেস মঞ্জুর করায় আমি পুনঃনির্দেশিত হইনি। তবে দায়বদ্ধতাটি রিফ্রেশ ছাড়াই অ্যাক্সেস টোকেন en কোন ধারনা?
seorch.me

@ seorch.me ক্রেজি মনে হচ্ছে তবে রিফ্রেশ টোকেনটি ব্যবহার করার জন্য আপনাকে কী নতুন $client( $client = new apiClient();) সেটআপ করতে হবে ?
জে কে।

4
@ seorch.me আপনাকে অনুমোদনের সময় একটি নতুন রিফ্রেশ টোকেন পাওয়ার $client->setApprovalPrompt('force')পাশাপাশি সেট করতে হবে $client->setAccessType('offline')। ব্যবহারকারীর অ্যাক্সেসের সুযোগ অনুমোদনের জন্য বাধ্য না করে, গুগল ধরে নিয়েছে আপনি পুরানো রিফ্রেশ টোকেন ব্যবহার করতে যাচ্ছেন।
জেসন

14

@ ইউরি-ওয়েগ পোস্ট করা উত্তরটি আমার পক্ষে কাজ করেছিল তবে আমি তার ব্যাখ্যাগুলি খুব স্পষ্টভাবে খুঁজে পাইনি, আমাকে এটির কিছুটা উচ্চারণ করুন।

প্রথম অ্যাক্সেস অনুমতি ক্রম চলাকালীন, কলব্যাকে, আপনি যখন একটি প্রমাণীকরণ কোড পাবেন সেই বিন্দুতে পৌঁছানোর পরে আপনাকে অবশ্যই অ্যাক্সেস টোকেন এবং রিফ্রেশ টোকনটি সংরক্ষণ করতে হবে ।

কারণটি হ'ল গুগল এপি আপনাকে অ্যাক্সেসের অনুমতি দেওয়ার জন্য অনুরোধ করলেই রিফ্রেশ টোকেন সহ অ্যাক্সেস টোকেন প্রেরণ করে। পরবর্তী অ্যাক্সেস টোকেনগুলি কোনও রিফ্রেশ টোকেন ছাড়াই পাঠানো হবে (আপনি approval_prompt=forceবিকল্পটি ব্যবহার না করে )।

আপনি প্রথমবার প্রাপ্ত রিফ্রেশ টোকেনটি ব্যবহারকারী অ্যাক্সেসের অনুমতি প্রত্যাহার না করা অবধি বৈধ থাকে।

সরলতর পিএইচপি-তে কলব্যাক সিকোয়েন্সের উদাহরণ হ'ল:

// init client
// ...

$authCode = $_GET['code'];
$accessToken = $client->authenticate($authCode);
// $accessToken needs to be serialized as json
$this->saveAccessToken(json_encode($accessToken));
$this->saveRefreshToken($accessToken['refresh_token']);

এবং পরে, সরল পিএইচপি-তে সংযোগ ক্রম হবে:

// init client
// ...

$accessToken = $this->loadAccessToken();
// setAccessToken() expects json
$client->setAccessToken($accessToken);

if ($client->isAccessTokenExpired()) {
    // reuse the same refresh token
    $client->refreshToken($this->loadRefreshToken());
    // save the new access token (which comes without any refresh token)
    $this->saveAccessToken($client->getAccessToken());
}

নিখুঁত, অনেক কাজ। কেবলমাত্র আমি যা বলতে চাই তা হ'ল আপনার ব্যাখ্যা করা উচিত যে আপনাকে জেসন অবজেক্টটি কেবল স্ট্রিং হিসাবে টোকেন হিসাবে পাস করতে হবে না।
অলিভার বেয়েস-শেলটন

@ অলিভারবায়েস-শেল্টন হাই ধন্যবাদ আমি ভেবেছিলাম // setAccessToken() expects jsonযথেষ্ট ছিল। নাকি কোডের অন্য অংশের জন্য?
দাইশি

এটি আমার পক্ষে দুর্দান্ত কাজ করে তবে আপনি কি জানেন যে এই কোডটি এমন পরিস্থিতি পরিচালনা করে যেখানে 50 টোকেন রিফ্রেশের সীমা অতিক্রম করার কারণে একটি টোকেনের মেয়াদ শেষ হয়ে যায়? 'টোকেন মেয়াদপূর্তির' সম্পর্কে বিস্তারিত এখানে পাওয়া যাবে: developers.google.com/identity/protocols/OAuth2#expiration
বিয়ন্সের

দেখে মনে হচ্ছে সর্বশেষতম 2.0 সংস্করণটি অ্যাক্সেস টোকেন অ্যারেতে রিফ্রেশ টোকেনটি ফিরিয়ে দিচ্ছে। এর অর্থ অ্যাক্সেস টোকেন সংরক্ষণ করা রিফ্রেশ টোকেনকেও সংরক্ষণ করে, যেমন রিফ্রেশ টোকেন অন্তর্ভুক্ত রয়েছে। রিফ্রেশ টোকেনের মেয়াদ শেষ হয়ে যাওয়ার প্রতিক্রিয়া হিসাবে, আমি অনুমান করছি যে পরীক্ষা করতে হবে এবং স্পষ্টভাবে পরিচালনা করতে হবে - মনে রাখবেন 50 সীমাটি "প্রতি ক্লায়েন্টের প্রতি ব্যবহারকারী", মানে এটি প্রতি ক্লায়েন্টের জন্য 50 তাই আপনার এটি আঘাতের সম্ভাবনা কম, বিশেষত যদি আপনি টোকেন একত্রিত করতে অন্তর্ভুক্ত স্কোপগুলি ব্যবহার করেন।
ব্রায়ান সি

8

আমি আমার প্রকল্পে কোডটি ব্যবহার করছি এবং এটি কার্যকরভাবে কাজ করছে:

public function getClient(){
    $client = new Google_Client();
    $client->setApplicationName(APPNAME);       // app name
    $client->setClientId(CLIENTID);             // client id
    $client->setClientSecret(CLIENTSECRET);     // client secret 
    $client->setRedirectUri(REDIRECT_URI);      // redirect uri
    $client->setApprovalPrompt('auto');

    $client->setAccessType('offline');         // generates refresh token

    $token = $_COOKIE['ACCESSTOKEN'];          // fetch from cookie

    // if token is present in cookie
    if($token){
        // use the same token
        $client->setAccessToken($token);
    }

    // this line gets the new token if the cookie token was not present
    // otherwise, the same cookie token
    $token = $client->getAccessToken();

    if($client->isAccessTokenExpired()){  // if token expired
        $refreshToken = json_decode($token)->refresh_token;

        // refresh the token
        $client->refreshToken($refreshToken);
    }

    return $client;
}

6

একই সমস্যা ছিল; আমার স্ক্রিপ্ট যা গতকাল কাজ করেছিল, কিছু অদ্ভুত কারণে আজ তা হয়নি। কোন পরিবর্তন নেই.

স্পষ্টতই এটি কারণ আমার সিস্টেমের ঘড়িটি 2.5 (!!) সেকেন্ডে বন্ধ ছিল, এনটিপির সাথে সিঙ্ক করে এটি স্থির করে।

আরও দেখুন: https://code.google.com/p/google-api-php-client/wiki/OAuth2# সলভিং_ইনওয়েড_গ্রান্ট_অরফেস


এই উত্তরটি আমাকে অনেক সাহায্য করেছে man আপনি সম্ভবত আমাকে অনেক সময় বাঁচিয়েছেন। অনেক! ধন্যবাদ! আমি sudo apt-get install ntpএনটিপি ইনস্টল করার জন্য কেবলমাত্র আমার দেবিয়ান মেশিনে মৃত্যুদন্ড কার্যকর করেছি। এটি ঘড়িটি সিঙ্ক্রোনাইজ করে এবং সমস্যাটি সমাধান করা হয়েছিল।
সিজমন সাদোও

4

এফওয়াইআই: Google.০ গুগল অ্যানালিটিক্স এপিআই আপনার অ্যাক্সেস টোকেনটি স্বয়ংক্রিয়ভাবে রিফ্রেশ করবে যদি আপনার স্ক্রিপ্টটির কখনই প্রয়োজন হয় না তাই এটি রিফ্রেশ টোকেনের মেয়াদ শেষ হয়ে যায় refreshToken

(এতে Signফাংশনটি দেখুন auth/apiOAuth2.php)


"স্বয়ংক্রিয়ভাবে রিফ্রেশ" এর অর্থ হ'ল আমাকে শুধু getAccessToken () জিজ্ঞাসা করতে হবে এবং আমি একটি রিফ্রেশ ফিরে পাব? তবে আমাকে প্রথমে ডিবি থেকে রিফ্রেশ টোকেন সেট করতে হবে, তাই না? অন্যথায়
রিফ্রেশটি

4

কখনও কখনও রিফ্রেশ টোকেন আমি ব্যবহার করে উত্পন্ন হয় না $client->setAccessType ("offline");

এটা চেষ্টা কর:

$client->setAccessType ("offline");
$client->setApprovalPrompt ("force"); 

আরও সুনির্দিষ্ট হওয়ার জন্য, দেখে মনে হচ্ছে রিফ্রেশ টোকেনটি আপনার প্রথম অনুমোদনে অন্তর্ভুক্ত রয়েছে । আপনি যদি সংরক্ষণ করে এবং এটি ব্যবহার করেন তবে আমি বিশ্বাস করি (অন্যদের মতে, যাচাই করা হয়নি) রিফ্রেশ টোকেনটি ফেরত দেওয়া অবিরত রয়েছে। ডকো আরও জানিয়েছে যে তারা যদি রিফ্রেশ টোকেন থাকে তবে অ্যাক্সেস টোকেনটি স্বতঃ-রিফ্রেশ করবে, যার অর্থ এটি নিরাপদে রিফ্রেশ টোকেন পরিচালনার বিষয় a setApprovalPrompt ('বল') পরে একটি রিফ্রেশ টোকেন জারি করতে বাধ্য করে; এটি ছাড়া আপনি অন্য একটি পাবেন না।
ব্রায়ান সি

2

আমি গুগল এপিআইয়ের বর্তমান সংস্করণ সহ স্মার্টকোডগুলি দ্বারা উদাহরণটি ব্যবহার করেছি, তবে এটি কার্যকর হয়নি। আমি মনে করি তার এপিআই খুব পুরানো।

সুতরাং, আমি এপিআই উদাহরণগুলির ভিত্তিতে সবেমাত্র নিজের সংস্করণটি লিখেছি ... এটি অ্যাক্সেস টোকেন, অনুরোধ টোকেন, টোকেন টাইপ, আইডি টোকেন, মেয়াদোত্তীকরণের সময় এবং তৈরির সময়টিকে স্ট্রিং হিসাবে আউটপুট করে

যদি আপনার ক্লায়েন্টের শংসাপত্র এবং বিকাশকারী কী সঠিক হয় তবে এই কোডটি বাক্সের বাইরে কাজ করা উচিত।

<?php
// Call set_include_path() as needed to point to your client library.
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_Oauth2Service.php';
session_start();

$client = new Google_Client();
$client->setApplicationName("Get Token");
// Visit https://code.google.com/apis/console?api=plus to generate your
// oauth2_client_id, oauth2_client_secret, and to register your oauth2_redirect_uri.
$oauth2 = new Google_Oauth2Service($client);

if (isset($_GET['code'])) {
    $client->authenticate($_GET['code']);
    $_SESSION['token'] = $client->getAccessToken();
    $redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
    header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
    return;
}

if (isset($_SESSION['token'])) {
    $client->setAccessToken($_SESSION['token']);
}

if (isset($_REQUEST['logout'])) {
    unset($_SESSION['token']);
    $client->revokeToken();
}
?>
<!doctype html>
<html>
    <head><meta charset="utf-8"></head>
    <body>
        <header><h1>Get Token</h1></header>
        <?php
        if ($client->getAccessToken()) {
            $_SESSION['token'] = $client->getAccessToken();
            $token = json_decode($_SESSION['token']);
            echo "Access Token = " . $token->access_token . '<br/>';
            echo "Refresh Token = " . $token->refresh_token . '<br/>';
            echo "Token type = " . $token->token_type . '<br/>';
            echo "Expires in = " . $token->expires_in . '<br/>';
            echo "ID Token = " . $token->id_token . '<br/>';
            echo "Created = " . $token->created . '<br/>';
            echo "<a class='logout' href='?logout'>Logout</a>";
        } else {
            $authUrl = $client->createAuthUrl();
            print "<a class='login' href='$authUrl'>Connect Me!</a>";
        }
        ?>
    </body>
</html>

4
দয়া করে, তুমি কেন আমাকে এই লাইন ব্যাখ্যা হতে পারে: $redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];। কেন আপনি একই পৃষ্ঠায় পুনর্নির্দেশ? এটি কি প্রয়োজনীয়?
ট্রপিক্যালিসা

@ ট্রপিক্যালিস্টা: প্রতি সেফ পৃষ্ঠাটি পুনরায় লোড করা প্রয়োজন হয় না, তবে সাধারণভাবে প্রমাণীকরণের প্রবাহটি এভাবে প্রয়োগ করা হয়।
জন স্লেজার

তবে অ্যাক্সেস টোকেনটির মেয়াদ শেষ হয়ে গেলে আপনি নতুন অ্যাক্সেস টোকেন পেতে রিফ্রেশ টোকেন ব্যবহার করছেন না।
অপদান

2

প্রাথমিক অনুমোদনের অনুরোধের সময় আপনাকে জেসন স্ট্রিং হিসাবে ফাইল বা ডেটাবেস-এ অ্যাক্সেস টোকেন সংরক্ষণ করতে হবে এবং অ্যাক্সেস টাইপটিকে অফলাইনে সেট করতে হবে $client->setAccessType("offline")

তারপরে, পরবর্তী এপিআই অনুরোধের সময়, আপনার ফাইল বা ডিবি থেকে অ্যাক্সেস টোকনটি ধরে তা ক্লায়েন্টের কাছে পৌঁছে দিন:

$accessToken = json_decode($row['token'], true);
$client->setAccessToken($accessToken);

এখন আপনার টোকেনটির মেয়াদ শেষ হয়ে গেছে কিনা তা পরীক্ষা করা দরকার:

if ($client->isAccessTokenExpired()) {
    // access token has expired, use the refresh token to obtain a new one
    $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
    // save the new token to file or db
    // ...json_encode($client->getAccessToken())

fetchAccessTokenWithRefreshToken()ফাংশন আপনার জন্য কাজ করতে এবং ফিরে আপনার ফাইল বা ডাটাবেস করার জন্য একটি নতুন অ্যাক্সেস টোকেন প্রদান তা রক্ষা করবে।


1

গুগল / গুগল-এপিআইপিএইচপি-ক্লায়েন্ট ভি ২.০.০-আরসি with এর সাথে আমারও একই সমস্যা আছে এবং ১ ঘন্টা অনুসন্ধান করার পরে আমি জেসন_নকোড ব্যবহার করে এই সমস্যাটি সমাধান করেছি :

    if ($client->isAccessTokenExpired()) {
        $newToken = json_decode(json_encode($client->getAccessToken()));
        $client->refreshToken($newToken->refresh_token);
        file_put_contents(storage_path('app/client_id.txt'), json_encode($client->getAccessToken()));
    }

1

এখানে এটি খুব ভাল কাজ করে, সম্ভবত এটি কারওর পক্ষে সহায়তা করতে পারে:

index.php

session_start();

require_once __DIR__.'/client.php';

if(!isset($obj->error) && isset($_SESSION['access_token']) && $_SESSION['access_token'] && isset($obj->expires_in)) {
?>
<!DOCTYPE html>
<html>
<head>
<title>Google API Token Test</title>
<meta charset='utf-8' />
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script>
search('Music Mix 2010');
function search(q) {
    $.ajax({
        type: 'GET',
        url: 'action.php?q='+q,
        success: function(data) {
            if(data == 'refresh') location.reload();
            else $('#response').html(JSON.stringify(JSON.parse(data)));
        }
    });
}
</script>
</head>
<body>
<div id="response"></div>
</body>
</html>
<?php
}
else header('Location: '.filter_var('https://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).'/oauth2callback.php', FILTER_SANITIZE_URL));
?>

oauth2callback.php

require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google_Client();
$client->setAuthConfigFile('auth.json');
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->setRedirectUri('https://'.filter_var($_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'], FILTER_SANITIZE_URL));
$client->addScope(Google_Service_YouTube::YOUTUBE_FORCE_SSL);

if(isset($_GET['code']) && $_GET['code']) {
    $client->authenticate(filter_var($_GET['code'], FILTER_SANITIZE_STRING));
    $_SESSION['access_token'] = $client->getAccessToken();
    $_SESSION['refresh_token'] = $_SESSION['access_token']['refresh_token'];
    setcookie('refresh_token', $_SESSION['refresh_token'], time()+60*60*24*180, '/', filter_var($_SERVER['HTTP_HOST'], FILTER_SANITIZE_URL), true, true);
    header('Location: '.filter_var('https://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']), FILTER_SANITIZE_URL));
    exit();
}
else header('Location: '.filter_var($client->createAuthUrl(), FILTER_SANITIZE_URL));
exit();

?>

ক্লায়েন্ট.এফপি

// https://developers.google.com/api-client-library/php/start/installation
require_once __DIR__.'/vendor/autoload.php';

$client = new Google_Client();
$client->setAuthConfig('auth.json');
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->addScope(Google_Service_YouTube::YOUTUBE_FORCE_SSL);

// Delete Cookie Token
#setcookie('refresh_token', @$_SESSION['refresh_token'], time()-1, '/', filter_var($_SERVER['HTTP_HOST'], FILTER_SANITIZE_URL), true, true);

// Delete Session Token
#unset($_SESSION['refresh_token']);

if(isset($_SESSION['refresh_token']) && $_SESSION['refresh_token']) {
    $client->refreshToken($_SESSION['refresh_token']);
    $_SESSION['access_token'] = $client->getAccessToken();
}
elseif(isset($_COOKIE['refresh_token']) && $_COOKIE['refresh_token']) {
    $client->refreshToken($_COOKIE['refresh_token']);
    $_SESSION['access_token'] = $client->getAccessToken();
}

$url = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.urlencode(@$_SESSION['access_token']['access_token']);
$curl_handle = curl_init();
curl_setopt($curl_handle, CURLOPT_URL, $url);
curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_USERAGENT, 'Google API Token Test');
$json = curl_exec($curl_handle);
curl_close($curl_handle);

$obj = json_decode($json);

?>

action.php

session_start();

require_once __DIR__.'/client.php';

if(isset($obj->error)) {
    echo 'refresh';
    exit();
}
elseif(isset($_SESSION['access_token']) && $_SESSION['access_token'] && isset($obj->expires_in) && isset($_GET['q']) && !empty($_GET['q'])) {
    $client->setAccessToken($_SESSION['access_token']);
    $service = new Google_Service_YouTube($client);
    $response = $service->search->listSearch('snippet', array('q' => filter_input(INPUT_GET, 'q', FILTER_SANITIZE_SPECIAL_CHARS), 'maxResults' => '1', 'type' => 'video'));
    echo json_encode($response['modelData']);
    exit();
}
?>

1

এই প্রশ্নটি মূলত পোস্ট হওয়ার পরে গুগল কিছু পরিবর্তন করেছে।

এখানে আমার বর্তমানে কাজ উদাহরণ।

    public function update_token($token){

    try {

        $client = new Google_Client();
        $client->setAccessType("offline"); 
        $client->setAuthConfig(APPPATH . 'vendor' . DIRECTORY_SEPARATOR . 'google' . DIRECTORY_SEPARATOR . 'client_secrets.json');  
        $client->setIncludeGrantedScopes(true); 
        $client->addScope(Google_Service_Calendar::CALENDAR); 
        $client->setAccessToken($token);

        if ($client->isAccessTokenExpired()) {
            $refresh_token = $client->getRefreshToken();
            if(!empty($refresh_token)){
                $client->fetchAccessTokenWithRefreshToken($refresh_token);      
                $token = $client->getAccessToken();
                $token['refresh_token'] = json_decode($refresh_token);
                $token = json_encode($token);
            }
        }

        return $token;

    } catch (Exception $e) { 
        $error = json_decode($e->getMessage());
        if(isset($error->error->message)){
            log_message('error', $error->error->message);
        }
    }


}

1

আমি গুগল-এপি-পিএইচপি-ক্লায়েন্ট ভি ২.২.২ ব্যবহার করি আমি প্যারাম fetchAccessTokenWithRefreshToken();ছাড়াই ফাংশন কল দিলে একটি নতুন টোকেন পাই , এটি একটি আপডেট অ্যাক্সেস টোকন দেয় এবং রিফ্রেশ টোকেনটি হারিয়ে না যায়।

if ($client->getAccessToken() && $client->isAccessTokenExpired()) {
    $new_token=$client->fetchAccessTokenWithRefreshToken();
    $token_data = $client->verifyIdToken();
}    

0

আপনার রিফ্রেশ টোকেন পেতে নিম্নলিখিত কোড স্নিপেট ব্যবহার করুন

    <?php

    require_once 'src/apiClient.php';
    require_once 'src/contrib/apiTasksService.php';

    $client = new apiClient();
    $client->setAccessType('offline');
    $tasksService = new apiTasksService($client);

    $auth = $client->authenticate();
    $token = $client->getAccessToken();
    // the refresh token
    $refresh_token = $token['refresh_token'];
    ?>

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.