草庐IT

javascript - 如何在分析 API 上设置访问 token ?

coder 2025-02-13 原文

我想知道,该文档包含以多种语言实现 Analytics API 使用的教程。

现在在 PHP 中,他们展示了如何存储访问 token 并维护它,现在我假设 JS 以某种方式将它保存在某种本地存储中,但我不希望用户每次访问时都进行身份验证,所以我的计划是将访问和刷新 token 保存在我的数据库中,并将其简单地应用于客户端,而不是经历所有弹出过程。

根据教程:

 gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: false}, result);

触发返回访问 token 的弹出窗口,但我会再说一遍,我有兴趣从数据库提交 token 。

如何做到这一点?

是否有一些 gapi.auth.setToken(token) 方法可以调用 Core Reporting API?

最佳答案

在已经编写了 PHP 以使用谷歌的 PHP 客户端库进行身份验证之后,我来到这里寻找使用它的解决方案。我想像您提到的那样共享存储的 token ,并且能够在不重新验证和/或触发弹出窗口的情况下使用 javascript(可能使用 .init(callback) 来解决这个问题方法,请参阅末尾的文档/链接)。

Is there some gapi.auth.setToken(token) method

事实证明你可以,你提到的正是 setToken(token) 函数,你甚至可以共享之前在 PHP 中生成的身份验证 token 。我还不确定的是,我们是否应该这样做:)

我正在使用 PHP 进行初始身份验证,但大概在 javascript 客户端中,您可以调用 setToken() 对您使用 getToken( ) 以与本示例相同的方式。可能还有更好的方法,比如 API 身份验证文档中提到的 CORS(见末尾的链接),我还没有机会调查其中的任何一个,但是,我可以举一个例子来回答这个问题,并且可能对需要相同行为的其他人有用

我首先找到了 Google 开发人员 Dan Holevoet 的博客文章,其中包含一些示例 JS 代码。

http://googleappsdeveloper.blogspot.com.au/2011/12/using-new-js-library-to-unlock-power-of.html

能够直接使用 javascript 查询 API 并动态加载列表等非常棒,但让我担心的当然是在 js 中存储 clientid 等。

// Snippet from Dan's post
var clientId = 'YOUR_CLIENT_ID';
var apiKey = 'YOUR_API_KEY';
var scopes = 'https://www.googleapis.com/auth/calendar';

function handleClientLoad() {
    gapi.client.setApiKey(apiKey);
    window.setTimeout(checkAuth,1);
    checkAuth();
}

但是,根据 Dan 对同一问题的回答:

The apiKey is used in conjunction with designated referrers, which you must declare in the APIs Console. If the key is sent from an unauthorized referrer, it will not work. You should make your accepted referrer list as limited as possible to ensure that others do not use your apiKey for their own requests.

现在,我的示例是针对日历 API 的,但它似乎也与其他 API 非常一致。

注意:此代码段仅用于概念验证目的,可能不应该用于生产。我假设提到的引荐来源网址保护使某些像可以这样做,但需要多加考虑。它可以通过隐藏输入、AJAX 调用等来完成。但最终,它们都将在 javascript 中可见。

我为测试这个概念所做的是:

  • 通过 PHP 客户端库进行身份验证,使用与回调相同的脚本/URL(有关这些回调,请参阅 [API 控制台][2])
  • 验证成功后,在回调中,将页面中的全局 javascript 变量设置为存储的 PHP 验证 token
  • 页面加载后,在第一次使用 javascript 的点击事件中(甚至在文档就绪时),调用 authMe() 设置 token
  • 然后照常进行,调用您在初始 PHP 身份验证过程中赋予范围的任何 javascript API 方法(在本例中为 makeApiCall())

像这样:

在 php 回调例程中,无论是否已通过身份验证(假设您的回调 URL 是相同的脚本),将此 var 设为全局

<script type="text/javascript">
    // A place to stick PHP's auth token once the auth dance is done
    var dodgey_global_access_token = {};
</script>

现在,在 php 回调例程中一旦我们检查了我们是否已通过身份验证$_SESSION['token'] = $client->getAccessToken(); 已被调用(IE 将身份验证 token 存储在某个地方以备后用),或者至少 $client->getAccessToken() 有一些有意义的东西:

<script type="text/javascript">
// Set the js var via PHP here.. Yeck... Note json encode in php and parse in jquery
dodgey_global_access_token = $.parseJSON (<?php  echo json_encode ($client->getAccessToken() ); ?>);
// dodgey_global_access_token now contains the auth token structure

// Removed auth-related functions in Dan's code - we'll already have a token

// Dan's orig function to list events in 'primary' calendar
function makeApiCall() {
  gapi.client.load('calendar', 'v3', function() {
    var request = gapi.client.calendar.events.list({
      'calendarId': 'primary'
    });

    request.execute(function(resp) {
      for (var i = 0; i < resp.items.length; i++) {
        var li = document.createElement('li');
        li.appendChild(document.createTextNode(resp.items[i].summary));
        document.getElementById('events').appendChild(li);
      }
    });
  });
}

// My function to setToken with the token injected from PHP authentication
function authMe () {
    // Stuff the token into the gapi object
    gapi.auth.setToken( dodgey_global_access_token );

    // Now call the original 'makeAPICall' function now that we're 'authenticated'
    makeApiCall();  
}
</script>

注意:我在我的示例中使用了 jquery 来快速解析 JSON,我们已经在项目中使用它,但如果没有,您将不得不找到另一个库来这样做

相关/有用的文档:

// Sorry, as a new poster I can only post 2 hyperlinks, 
// so embedding this in code snippet
// 
//    http://code.google.com/p/google-api-javascript-client/wiki/ReferenceDocs#gapi
//    http://code.google.com/p/google-api-javascript-client/wiki/Authentication
//    http://code.google.com/p/google-api-javascript-client/issues/detail?id=22
//    http://code.google.com/p/google-api-javascript-client/wiki/CORS
//    https://code.google.com/apis/console

如果有任何不清楚的地方,请告诉我,并且可以发布工作示例进行演示。

关于javascript - 如何在分析 API 上设置访问 token ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13704714/

有关javascript - 如何在分析 API 上设置访问 token ?的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  3. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  4. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  5. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  6. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  7. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  8. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  9. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  10. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

随机推荐