有人曾经为google api维护过OAuth2 refresh_token,我可以和你比较一下代码吗?文档说,如果我用access _ type:“offline”创建access_token,客户端api将在到期前自动使用refresh_token,但在我的情况下,这种情况只发生一次,此时refresh_token从更新的token对象中消失。我的代码就这么简单:
async function google(request)
{let [{google},keys]=await Promise.all(
[import("./node_modules/googleapis/build/src/index.js")
,import("./keys.json").then(json=>json.default)
]);
let {client,secret,token}=keys;
let authority=new google.auth.OAuth2(client,secret,request.url);
authority.on('tokens',token=>save("keys.json",{...keys,token}).then(console.log));
if(!token)
if(!request.query.code)
return authority.generateAuthUrl({scope,access_type:"offline",prompt:"consent"});
else return new Promise(resolve=>
authority.getToken(request.query.code,resolve)).then(fail=>fail||"new access_token");
authority.setCredentials(token);
google=google.sheets({version:"v4",auth:authority});
return new Promise(resolve=>
google.spreadsheets.values.get(sheet,resolve)).then(fail=>fail||"valid token");
// first return value: [consent url redirecting to the same endpoint]
// after using the url: "new access_token"
// during the next 2 hours: "valid token" ("refresh_token" gone missing from keys.json in the second hour)
// after 2 hours: "Error: missing required parameter: refresh_token"
}
可能是因为我在每个请求上动态地重新验证API?我也每次都设置凭据,因此与拥有静态API没有任何区别
我对DalmTo的回答的评论被证明是正确的:access_token的refresh_token是静态的,所以问题是当保存新令牌时,必须保留refresh_token。在文档中提到这一点可能也是有用的,除非是这样,我只是错过了这个细节。
这是我手头上最好的例子,它使用不同的API,但应该给你一个想法。
库不为您保存或加载。但是,它确实支持将刷新令牌加载到其中。因此,只要您将它保存在某个位置,然后在正确的时间加载它,它就会工作。
检查我如何使用TOKEN_PATH
这是存储令牌的路径。当代码首次运行时,系统将尝试读取该文件并加载存储在其中的任何令牌。
请注意,刷新令牌只会在第一次使用时返回给您,如果您需要它,您需要保存它。而不是意外地用null覆盖它。
“自述文件”中有很多关于如何设置的信息。Google api node.js客户端
const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');
const dotenv = require('dotenv');
dotenv.config();
const CRED_FILE_PATH = process.env.API_CREDS;
console.log(`Your cred path is ${CRED_FILE_PATH}`); // ../creds.json
const VIEW_ID = process.env.VIEW_ID;
console.log(`Your view id is ${VIEW_ID}`);
// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/analytics.readonly'];
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
const TOKEN_PATH = 'token.json';
// Load client secrets from a local file.
fs.readFile(CRED_FILE_PATH, (err, content) => {
if (err) return console.log('Error loading client secret file:', err);
// Authorize a client with credentials, then call the Google Drive API.
authorize(JSON.parse(content), getUserReport);
});
/**
* Create an OAuth2 client with the given credentials, and then execute the
* given callback function.
* @param {Object} credentials The authorization client credentials.
* @param {function} callback The callback to call with the authorized client.
*/
function authorize(credentials, callback) {
const {client_secret, client_id, redirect_uris} = credentials.installed;
const oAuth2Client = new google.auth.OAuth2(
client_id, client_secret, redirect_uris[0]);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, (err, token) => {
if (err) return getAccessToken(oAuth2Client, callback);
oAuth2Client.setCredentials(JSON.parse(token));
callback(oAuth2Client);
});
}
/**
* Get and store new token after prompting for user authorization, and then
* execute the given callback with the authorized OAuth2 client.
* @param {google.auth.OAuth2} oAuth2Client The OAuth2 client to get token for.
* @param {getEventsCallback} callback The callback for the authorized client.
*/
function getAccessToken(oAuth2Client, callback) {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
console.log('Authorize this app by visiting this url:', authUrl);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
oAuth2Client.getToken(code, (err, token) => {
if (err) return console.error('Error retrieving access token', err);
oAuth2Client.setCredentials(token);
// Store the token to disk for later program executions
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) return console.error(err);
console.log('Token stored to', TOKEN_PATH);
});
callback(oAuth2Client);
});
});
}
我有一个谷歌云,我想推我的图像。 我的图片是Hello-world项目与节点快递谷歌云客户端libray 你可以在我的github上找到它 https://github.com/innostarterkit/language 当我试着推的时候,我有这个错误 推送是指存储库[eu.gcr.io/innovation xxx/hello]a419c4413fb0:推送[================
我正在编写一个类,用于创建对BigQuery和Google云存储的授权。 在过去,我曾使用,但已被弃用。我试图使用,但我发现它只允许我使用,而我需要。 我知道可以从转换为,但我不知道如何将它们转换成相反的方向(转换为)。例如,我像这样创建连接: 有人能给我指明如何实现这一目标的方向吗? 谢谢!
我正在尝试使用我的应用程序中的google帐户登录用户。当用户第一次在我的应用程序中使用google帐户登录时,我遇到了一个问题。它显示了以下错误:传递给Illumb\Auth\Guard::login()的参数1必须实现interface Illumb\Auth\UserInterface,在我的控制器中为空我有以下信息: 我知道问题出在Auth::login($user);因为插入与Auth:
我试图访问我的用户的google drive内容。我可以使用带有正确参数的google drive用户许可url在我的域名上兑换代码:https://accounts.google.com/o/oauth2/v2/auth?响应类型=代码 我正在尝试向https://www.googleapis.com/oauth2/v4/tokenendpoint执行角$超文本传输协议请求。请求如下所示: 然而
我将appengine gcs客户端添加到我的Google appengine标准项目中: (此页上的说明如下:https://cloud.google.com/appengine/docs/standard/java/googlecloudstorageclient/setting-up-cloud-storage) 编译项目会引发以下错误(几天前没有问题): [错误]无法在项目myprojec
当您使用Google Drive Web客户端时,您可以第一次选择要连接的Google帐户。完成后续调用后,跳过您可以选择帐户的步骤——您不必再次授权。有没有办法在不实际退出Google帐户的情况下再次触发帐户选择? 我正在使用文件选择器API,参见https://developers.google.com/picker/docs/