简体   繁体   English

如何将服务OAuth access_token从PHP传递到JavaScript

[英]How to pass Service OAuth access_token from PHP to JavaScript

I am working on an application that is using Google Cloud Storage. 我正在使用Google Cloud Storage的应用程序上工作。 I would like to use the JSON_API to manage uploading/downloading the pictures our user's provide. 我想使用JSON_API来管理用户提供的图片的上传/下载。 My goal is to grab the access_token using my service account method, and pass it off the the JSON_API JavaScript client api. 我的目标是使用我的服务帐户方法获取access_token,并将其从JSON_API JavaScript客户端api中传递出去。

Here's my fancy pants class to grab the access_token: 这是我的上学裤子课,介绍access_token:

<?php

require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_StorageService.php';

class Model_Storage_Auth
{
    const CLIENT_ID = "clientid.apps.googleusercontent.com";
    const SERVICE_ACCOUNT_NAME = "accountname@developer.gserviceaccount.com";
    const KEY_FILE = "/super/secret/path/key.p12";
    const ACCESS_TOKEN = 'access_token';
    const APP_NAME = 'Fancy App';

    private $google_client;

    function __construct()
    {
        $this->google_client = new Google_Client();
        $this->google_client->setApplicationName(self::APP_NAME);
    }

    public function getToken()
    {
        //return '{}';
        if(is_null($this->google_client->getAccessToken()))
        {
            try{$this->google_client->setAccessToken(Session::get(self::ACCESS_TOKEN, '{}'));}catch(Exception $e){}
            if(is_null($this->google_client->getAccessToken()))
            {
                $scope = array();
                $scope[] = 'https://www.googleapis.com/auth/devstorage.full_control';
                $key = file_get_contents(self::KEY_FILE);
                $this->google_client->setAssertionCredentials(new Google_AssertionCredentials(
                    self::SERVICE_ACCOUNT_NAME,
                    $scope,
                    $key)
                );
                $this->google_client->setClientId(self::CLIENT_ID);
                Google_Client::$auth->refreshTokenWithAssertion();
                $token = $this->google_client->getAccessToken();
                Session::set(self::ACCESS_TOKEN, $token);
            }
        }
        return $this->google_client->getAccessToken();
    }

}

I took the google JavaScript example and modified it a little bit to try to add my implementation, here it is: 我以Google JavaScript示例为例,对其进行了一些修改以尝试添加我的实现,这里是:

<?php
$access_token = json_decode(html_entity_decode($access_token), true);
?>

<!--
  Copyright (c) 2012 Google Inc.

  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  use this file except in compliance with the License. You may obtain a copy of
  the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  License for the specific language governing permissions and limitations under
  the License.

  To run this sample, replace YOUR_API_KEY with your application's API key.
  It can be found at https://code.google.com/apis/console under API
  Access. Activate the Google Cloud Storage service at
  https://code.google.com/apis/console/ under Services
-->
<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8' />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script src="https://apis.google.com/js/client.js"></script>
    <script type="text/javascript">

    /**
     * The number of your Google Cloud Storage Project.
     */
    var projectNumber = 'HAS REAL NUMBER IN MINE';

    /**
     * Enter a client ID for a web application from the Google Developer
     * Console. In your Developer Console project, add a JavaScript origin
     * that corresponds to the domain from where you will be running the
     * script.
     */
    var clientId = 'YOUR_CLIENT_ID';

    /**
     * Enter the API key from the Google Developer Console, by following these
     * steps:
     * 1) Visit https://code.google.com/apis/console/?api=storage
     * 2) Click on "API Access" in the left column
     * 3) Find section "Simple API Access" and use the "API key." If sample is
     * being run on localhost then delete all "Referers" and save. Setting 
     * should display "Any referer allowed."
     */
    var apiKey = 'YOUR_API_KEY';

    /**
     * To enter one or more authentication scopes, refer to the documentation
     * for the API.
     */
    var scopes = 'https://www.googleapis.com/auth/devstorage.full_control';

    /**
     * Constants for request parameters. Fill these values in with your custom
     * information.
     */
    var API_VERSION = 'v1beta1';
    var PROJECT = projectNumber;

    /**
     * The name of the new bucket to create.
     */
    var BUCKET = 'code-sample-bucket';

    /**
     * The name of the object inserted via insertObject method.  
     */
    var object = "";

    /**
     * Get this value from the API console.
     */
    var GROUP = 
    'group-0000000000000000000000000000000000000000000000000000000000000000';

    /**
     * Valid values are user-userId, user-email, group-groupId, group-email,
     * allUsers, allAuthenticatedUsers
     */
    var ENTITY = 'allUsers';

    /**
     * Valid values are READER, OWNER
     */
    var ROLE = 'READER';

    /**
     * Valid values are READER, OWNER
     */
    var ROLE_OBJECT = 'READER';

    /**
     * A list of example calls to the Google Cloud Storage JavaScript client
     * library, as well as associated explanations of each call.
     */
    var listApiRequestExplanations = {
      'listBuckets': 'This API call queries the Google Cloud Storage API ' +
        'for a list of buckets in your project, and returns the result as ' +
        'a list of Google Cloud Storage buckets.',

      'listObjects': 'This API call queries the Google Cloud Storage API ' +
        'for a list of objects in your bucket, and returns the result as ' +
        'a list of Google Cloud Storage objects.',

      'listBucketsAccessControls': 'This API call queries the Google Cloud ' +
        'Storage API for the list of access control lists on buckets in your ' +
        'project and returns the result as a list of Google Cloud Storage ' +
        'Access Control Lists.',

      'listObjectsAccessControls': 'This API call queries the Google Cloud ' +
        'Storage API for the list of access control lists on objects in your ' +
        'bucket and returns the result as a list of Google Cloud Storage ' +
        'Access Control Lists.',

      'getBucket': 'This API call queries the Google Cloud Storage API ' +
        'for a bucket in your project, and returns the result as a ' +
        'Google Cloud Storage bucket.',

      'getBucketAccessControls': 'This API call queries the Google Cloud ' +
        'Storage API for the access control list on a specific bucket ' +
        'and returns the result as a Google Cloud Storage Access Control List.',

      'getObjectAccessControls': 'This API call queries the Google Cloud ' +
        'Storage API for the access control list on a specific object ' +
        'and returns the result as a Google Cloud Storage Access Control List.',

      'insertBucket': 'This API call uses the Google Cloud Storage API ' +
        'to insert a bucket into your project.',

      'insertObject': 'This API call uses the Google Cloud Storage API ' +
        'to insert an object into your bucket.',

      'insertBucketAccessControls': 'This API uses the Google Cloud ' +
        'Storage API to insert an access control list on a specific bucket ' +
        'and returns the result as a Google Cloud Storage Access Control List.',

      'insertObjectAccessControls': 'This API uses the Google Cloud ' +
        'Storage API to insert an access control list on a specific object ' +
        'and returns the result as a Google Cloud Storage Access Control List.',

      'deleteBucket': 'This API uses the Google Cloud Storage API to delete ' +
        'an empty bucket and returns an empty response to indicate success.',

      'deleteObject': 'This API uses the Google Cloud Storage API to delete ' +
        'an object and returns an empty response to indicate success.'
    };

    /**
     * Google Cloud Storage API request to retrieve the list of buckets in
     * your Google Cloud Storage project.
     */
    function listBuckets() {
      var request = gapi.client.storage.buckets.list({
        'projectId': PROJECT
      });
      executeRequest(request, 'listBuckets');
    }

    /**
     * Google Cloud Storage API request to retrieve the list of objects in
     * your Google Cloud Storage project.
     */
    function listObjects() {
      var request = gapi.client.storage.objects.list({
        'bucket': BUCKET
      });
      executeRequest(request, 'listObjects');
    }

    /**
     * Google Cloud Storage API request to retrieve the access control list on
     * a bucket in your Google Cloud Storage project.
     */
    function listBucketsAccessControls() {
      var request = gapi.client.storage.bucketAccessControls.list({
          'bucket': BUCKET
      });
      executeRequest(request, 'listBucketsAccessControls');
    }

    /**
     * Google Cloud Storage API request to retrieve the access control list on
     * an object in your Google Cloud Storage project.
     */
    function listObjectsAccessControls() {
      var request = gapi.client.storage.objectAccessControls.list({
          'bucket': BUCKET,
          'object': object
      });
      executeRequest(request, 'listObjectsAccessControls');
    }

    /**
     * Google Cloud Storage API request to retrieve a bucket in
     * your Google Cloud Storage project.
     */
    function getBucket() {
      var request = gapi.client.storage.buckets.get({
        'bucket': BUCKET
      });
      executeRequest(request, 'getBucket');
    }

    /**
     * Google Cloud Storage API request to retrieve a bucket's Access Control
     * List in your Google Cloud Storage project.
     */
    function getBucketAccessControls() {
      var request = gapi.client.storage.bucketAccessControls.get({
        'bucket': BUCKET,
        'entity': GROUP
      });
      executeRequest(request, 'getBucketAccessControls');
    }

    /**
     * Google Cloud Storage API request to retrieve an object's Access Control
     * List in your Google Cloud Storage project.
     */
    function getObjectAccessControls() {
      var request = gapi.client.storage.objectAccessControls.get({
        'bucket': BUCKET,
        'object': object,
        'entity': GROUP
      });
      executeRequest(request, 'getObjectAccessControls');
    }

    /**
     * Google Cloud Storage API request to insert a bucket into
     * your Google Cloud Storage project.
     */
    function insertBucket() {
      resource = {
        'id': BUCKET,
        'projectId': PROJECT
      };

      var request = gapi.client.storage.buckets.insert({
          'resource': resource
      });
      executeRequest(request, 'insertBucket');
    }

    /**
     * Google Cloud Storage API request to insert an object into
     * your Google Cloud Storage bucket.
     */
    function insertObject(event) {
      try{
        var fileData = event.target.files[0];
      } 
      catch(e) {
        //'Insert Object' selected from the API Commands select list
        //Display insert object button and then exit function
        filePicker.style.display = 'block';
        return;
      }
      const boundary = '-------314159265358979323846';
      const delimiter = "\r\n--" + boundary + "\r\n";
      const close_delim = "\r\n--" + boundary + "--";

      var reader = new FileReader();
      reader.readAsBinaryString(fileData);
      reader.onload = function(e) {
        var contentType = fileData.type || 'application/octet-stream';
        var metadata = {
          'name': fileData.name,
          'mimeType': contentType
        };

        var base64Data = btoa(reader.result);
        var multipartRequestBody =
          delimiter +
          'Content-Type: application/json\r\n\r\n' +
          JSON.stringify(metadata) +
          delimiter +
          'Content-Type: ' + contentType + '\r\n' +
          'Content-Transfer-Encoding: base64\r\n' +
          '\r\n' +
          base64Data +
          close_delim;

        //Note: gapi.client.storage.objects.insert() can only insert
        //small objects (under 64k) so to support larger file sizes
        //we're using the generic HTTP request method gapi.client.request()
        var request = gapi.client.request({
          'path': '/upload/storage/v1beta2/b/' + BUCKET + '/o',
          'method': 'POST',
          'params': {'uploadType': 'multipart'},
          'headers': {
            'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
          },
          'body': multipartRequestBody});
          //Remove the current API result entry in the main-content div
          listChildren = document.getElementById('main-content').childNodes;
          if (listChildren.length > 1) {
            listChildren[1].parentNode.removeChild(listChildren[1]);
          }
        try{
          //Execute the insert object request
          executeRequest(request, 'insertObject');
          //Store the name of the inserted object 
          object = fileData.name;     
        }
        catch(e) {
          alert('An error has occurred: ' + e.message);
        }
      }
    }

    /**
     * Google Cloud Storage API request to insert an Access Control List into
     * your Google Cloud Storage bucket.
     */
    function insertBucketAccessControls() {
      resource = {
        'entity': ENTITY,
        'role': ROLE
      };

      var request = gapi.client.storage.bucketAccessControls.insert({
          'bucket': BUCKET,
          'resource': resource
      });
      executeRequest(request, 'insertBucketAccessControls');
    }

    /**
     * Google Cloud Storage API request to insert an Access Control List into
     * your Google Cloud Storage object.
     */
    function insertObjectAccessControls() {
      resource = {
        'entity': ENTITY,
        'role': ROLE_OBJECT
      };

      var request = gapi.client.storage.objectAccessControls.insert({
          'bucket': BUCKET,
          'object': object,
          'resource': resource
      });
      executeRequest(request, 'insertObjectAccessControls');
    }

    /**
     * Google Cloud Storage API request to delete a Google Cloud Storage bucket.
     */
    function deleteBucket() {
      var request = gapi.client.storage.buckets.delete({
          'bucket': BUCKET
      });
      executeRequest(request, 'deleteBucket');
    }

    /**
     * Google Cloud Storage API request to delete a Google Cloud Storage object.
     */
    function deleteObject() {
      var request = gapi.client.storage.objects.delete({
          'bucket': BUCKET,
          'object': object
      });
      executeRequest(request, 'deleteObject');
    }

    /**
     * Removes the current API result entry in the main-content div, adds the
     * results of the entry for your function.
     * @param {string} apiRequestName The name of the example API request.
     */
    function updateApiResultEntry(apiRequestName) {
      listChildren = document.getElementById('main-content')
        .childNodes;
      if (listChildren.length > 1) {
        listChildren[1].parentNode.removeChild(listChildren[1]);
      }
      if (apiRequestName != 'null') {
        window[apiRequestName].apply(this);
      }
    }

    /**
     * Determines which API request has been selected, and makes a call to add
     * its result entry.
     */
    function runSelectedApiRequest() {
      var curElement = document.getElementById('api-selection-options');
      var apiRequestName = curElement.options[curElement.selectedIndex].value;
      updateApiResultEntry(apiRequestName);
    }

    /**
     * Binds event listeners to handle a newly selected API request.
     */
    function addSelectionSwitchingListeners() {
      document.getElementById('api-selection-options')
        .addEventListener('change',
      runSelectedApiRequest, false);
    }

    /**
     * Template for getting JavaScript sample code snippets.
     * @param {string} method The name of the Google Cloud Storage request
     * @param {string} params The parameters passed to method
     */
    function getCodeSnippet(method, params) {
      var objConstruction = "// Declare your parameter object\n";
      objConstruction += "var params = {};";
      objConstruction += "\n\n";

      var param = "// Initialize your parameters \n";
      for (i in params) {
        param += "params['" + i + "'] = ";
        param += JSON.stringify(params[i], null, '\t');
        param += ";";
        param += "\n";
      }
      param += "\n";

      var methodCall = "// Make a request to the Google Cloud Storage API \n";
      methodCall += "var request = gapi.client." + method + "(params);";
      return objConstruction + param + methodCall;
    }


    /**
     * Executes your Google Cloud Storage request object and, subsequently,
     * inserts the response into the page.
     * @param {string} request A Google Cloud Storage request object issued
     *    from the Google Cloud Storage JavaScript client library.
     * @param {string} apiRequestName The name of the example API request.
     */
    function executeRequest(request, apiRequestName) {
      request.execute(function(resp) {
        console.log(resp);
        var apiRequestNode = document.createElement('div');
        apiRequestNode.id = apiRequestName;

        var apiRequestNodeHeader = document.createElement('h2');
        apiRequestNodeHeader.innerHTML = apiRequestName;

        var apiRequestExplanationNode = document.createElement('div');
        apiRequestExplanationNode.id = apiRequestName + 'RequestExplanation';

        var apiRequestExplanationNodeHeader = document.createElement('h3');
        apiRequestExplanationNodeHeader.innerHTML = 'API Request Explanation';
        apiRequestExplanationNode.appendChild(apiRequestExplanationNodeHeader);

        var apiRequestExplanationEntry = document.createElement('p');
        apiRequestExplanationEntry.innerHTML = 
          listApiRequestExplanations[apiRequestName];
        apiRequestExplanationNode.appendChild(apiRequestExplanationEntry);

        apiRequestNode.appendChild(apiRequestNodeHeader);
        apiRequestNode.appendChild(apiRequestExplanationNode);

        var apiRequestCodeSnippetNode = document.createElement('div');
        apiRequestCodeSnippetNode.id = apiRequestName + 'CodeSnippet';

        var apiRequestCodeSnippetHeader = document.createElement('h3');
        apiRequestCodeSnippetHeader.innerHTML = 'API Request Code Snippet';
        apiRequestCodeSnippetNode.appendChild(apiRequestCodeSnippetHeader);

        var apiRequestCodeSnippetEntry = document.createElement('pre');

        //If the selected API command is not 'insertObject', pass the request
        //paramaters to the getCodeSnippet method call as 'request.B.rpcParams'
        //else pass request paramaters as 'request.B' 
        if (apiRequestName != 'insertObject') {
          apiRequestCodeSnippetEntry.innerHTML = 
            getCodeSnippet(request.B.method, request.B.rpcParams);
          //Selected API Command is not 'insertObject'
          //hide insert object button
          filePicker.style.display = 'none';
        } else {
          apiRequestCodeSnippetEntry.innerHTML = 
            getCodeSnippet(request.B.method, request.B);
        }
        apiRequestCodeSnippetNode.appendChild(apiRequestCodeSnippetEntry);
        apiRequestNode.appendChild(apiRequestCodeSnippetNode);

        var apiResponseNode = document.createElement('div');
        apiResponseNode.id = apiRequestName + 'Response';

        var apiResponseHeader = document.createElement('h3');
        apiResponseHeader.innerHTML = 'API Response';
        apiResponseNode.appendChild(apiResponseHeader);

        var apiResponseEntry = document.createElement('pre');
        apiResponseEntry.innerHTML = JSON.stringify(resp, null, ' ');

        apiResponseNode.appendChild(apiResponseEntry);
        apiRequestNode.appendChild(apiResponseNode);

        var content = document.getElementById('main-content');
        content.appendChild(apiRequestNode);
      });
    }

    /**
     * Set required API keys and check authentication status.
     */
    function handleClientLoad() {
      gapi.client.setApiKey(apiKey);
      window.setTimeout(checkAuth, 1);
    }

    /**
     * Authorize Google Cloud Storage API.
     */
    function checkAuth() {
      gapi.auth.authorize({
        client_id: clientId,
        scope: scopes,
        immediate: true
      }, handleAuthResult);
    }

    /**
     * Handle authorization.
     */
    function handleAuthResult(authResult) {
      var authorizeButton = document.getElementById('authorize-button');
      if (authResult && !authResult.error) {
        authorizeButton.style.visibility = 'hidden';
        initializeApi();
    filePicker.onchange = insertObject;
      } else {
        authorizeButton.style.visibility = '';
        authorizeButton.onclick = handleAuthClick;
      } console.log(gapi.auth);
    }

    /**
     * Handle authorization click event.
     */
    function handleAuthClick(event) {
      gapi.auth.authorize({
        client_id: clientId,
        scope: scopes,
        immediate: false
      }, handleAuthResult);
      return false;
    }

    /**
     * Load Google Cloud Storage API v1beta12.
     */
    function initializeApi() {
      gapi.client.load('storage', API_VERSION);
    }

    /**
     * Driver for sample application.
     */
    $(window)
      .bind('load', function() {
        gapi.auth.setToken('<?php print $access_token["access_token"]; ?>');
        gapi.auth.token= '<?php print $access_token["access_token"]; ?>';
        console.log(gapi.auth.getToken());
        addSelectionSwitchingListeners();
        handleClientLoad();
    });
    </script>
  </head>
  <body>
    <!--Add a button for the user to click to initiate auth sequence -->
    <button id="authorize-button" style="visibility: hidden">Authorize</button>
    <header>
      <h1>Google Cloud Storage JavaScript Client Library Application</h1>
    </header>
    <label id="api-label">Try a sample API call!</label>
    <select id="api-selection-options">
      <option value="null">
        Please select an example API call from the dropdown menu
      </option>
      <option value="listBuckets">
        List Buckets
      </option>
      <option value="listObjects">
        List Objects
      </option>
      <option value="listBucketsAccessControls">
        List Buckets Access Control List
      </option>
      <option value="listObjectsAccessControls">
        List Objects Access Control List
      </option>
      <option value="getBucket">
        Get Bucket
      </option>
      <option value="getBucketAccessControls">
        Get Bucket Access Controls
      </option>
      <option value="getObjectAccessControls">
        Get Object Access Controls
      </option>
      <option value="insertBucket">
        Insert Bucket
      </option>
      <option value="insertObject">
        Insert Object
      </option>
      <option value="insertBucketAccessControls">
        Insert Bucket Access Controls
      </option>
      <option value="insertObjectAccessControls">
        Insert Object Access Controls
      </option>
      <option value="deleteBucket">
        Delete Bucket
      </option>
      <option value="deleteObject">
        Delete Object
      </option>
    </select>
    <br/>
    <input type="file" id="filePicker" style="display: none" />
    <div id="main-content">
    </div>
  </body>
</html>

Does anyone have any ideas? 有人有什么想法吗? I'm not being successful because my console prints this out: 我没有成功,因为我的控制台将输出以下内容:

as an error loading the page https://accounts.google.com/o/oauth2/auth?client_id=YOUR_CLIENT_ID&scope=ht…ifechurch.tv&response_type=token&state=412841043%7C0.2670569503&authuser=0

While it is possible to retrieve an access token in your server code for a service account, and then include that as part of a web-page or Javascript response to allow a browser direct access to Google Cloud Storage - this is generally a very dangerous approach, as the access token will allow anyone who has it full access to all of your Cloud Storage resources - without opportunity for your trusted server-side code to be able to apply access control restrictions specific to your application (for example to allow a user of your application only to upload/downloads files/object they should have access to). 虽然可以在服务器代码中检索服务帐户的访问令牌,然后将其包含在网页或Javascript响应中,以允许浏览器直接访问Google Cloud Storage,但这通常是非常危险的方法,因为访问令牌将使拥有访问令牌的任何人都拥有对您所有Cloud Storage资源的完全访问权限,而无需您信任的服务器端代码就可以应用特定于您应用程序的访问控制限制(例如,允许您的应用程序仅用于上传/下载他们应该有权访问的文件/对象)。

Direct file upload/download to Cloud Storage can however be achieved a slightly different way. 但是,可以将文件直接上传/下载到Cloud Storage的方式略有不同。 Google Cloud Storage supports a signed URL - this is a URL that you can generate in your server code (using the same private key you used to get an access token) that allows the bearer the ability to upload or download a specific file for a specific period of time. Google云端存储支持签名的URL-您可以在服务器代码中生成的URL(使用与获取访问令牌相同的私钥),使承载者可以上传或下载特定文件的特定文件一段的时间。

Documentation for this can be found here: https://developers.google.com/storage/docs/accesscontrol#Signed-URLs 可以在以下位置找到有关此文档的信息: https : //developers.google.com/storage/docs/accesscontrol#Signed-URLs

And an example from PHP here: https://groups.google.com/forum/#!msg/google-api-php-client/jaRYDWdpteQ/xbNTLfDhUggJ 还有一个来自PHP的示例: https : //groups.google.com/forum/#!msg/google-api- php-client/ jaRYDWdpteQ/xbNTLfDhUggJ

Once you generate this URL on your server you can pass to the browser, which in turn can then PUT directly to that URL, or GET directly from it without the need to use any special Google Javascript libraries. 在服务器上生成此URL后,您可以传递到浏览器,然后浏览器可以直接将其PUT到该URL,或直接从该URL进行获取,而无需使用任何特殊的Google Javascript库。 See for an example: Google Storage REST PUT With Signed URLs 参见示例: 带有签名URL的Google Storage REST PUT

I have recently completed a similar project using Ajax to access my PHP class which controls the access token renewals, connection URls etc. As it a live connection over HTTPS no sensitive information is visible in code and I can then load the relevant data directly into javascript. 我最近完成了一个类似的项目,使用Ajax访问我的PHP类,该类控制访问令牌的更新,连接URls等。由于它是通过HTTPS进行的实时连接,因此代码中看不到任何敏感信息,然后我可以将相关数据直接加载到javascript中。

Hope this helps 希望这可以帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何存储从OAuth获得的access_token供以后使用? - How to store the access_token gained from OAuth for later use? 如何解决OAuth 2.0中的access_token - how to solve access_token in OAuth 2.0 如何从Java服务器将Google api access_token传递给gapi javascript客户端? - How can I pass a google api access_token from java server to gapi javascript client? Twitter API调用仅使用javascript获取OAuth的access_token - Twitter API call to get access_token of OAuth only with javascript 在javascript中测试oauth2隐式授权access_token的解析器 - Testing parser for oauth2 implicit grant access_token in javascript 如何将access_token从Dom传递或解析到一个变量,然后可以存储和调用access_token? - How do I pass or parse that access_token from the Dom to a Variable I can then Store and call for access_token? 如何在纯客户端应用程序中从Google OAuth 2.0 API刷新access_token? - How to refresh access_token from Google OAuth 2.0 API in a pure client-side application? 如何使用jQuery(localhost)获得oauth access_token? - How to get oauth access_token with jQuery (localhost)? 存储access_token-JavaScript - Storing access_token - javascript oAuth 2.0,access_token,Facebook,Twitter - oAuth 2.0, access_token, Facebook, Twitter
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM