英文:
Google Tasks Authentication: Handle refresh tokens for Embedded Devices
问题
我正在为一个个人嵌入式设备(Visionect电子墨水显示屏)开发应用,该设备可以运行一些Node.js代码来显示我的Google任务。它运行良好,但访问令牌定期过期。我应该如何处理令牌过期?当然,我不能在这个电子墨水显示屏上显示登录屏幕。我如何永久拥有可以一直工作,直到用户(在这种情况下只有一个用户 - 我)撤销访问令牌的代码?
我查看了这个答案,但我不确定它是否回答了我的问题:https://stackoverflow.com/questions/53786782/google-api-authentication-tasks-api/53787724#53787724
以下是我的代码:
/*
credentials.json:
{
"installed": {
"client_id": "XXXXXXX.apps.googleusercontent.com",
"project_id": "XXXXXXX",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "XXXXXXX",
"redirect_uris": [
"http://localhost"
]
}
}
*/
import fs from 'fs'
import path from 'path'
import process from 'process'
import {authenticate} from '@google-cloud/local-auth'
const SCOPES = ['https://www.googleapis.com/auth/tasks.readonly']
const CREDENTIALS_PATH = path.join(process.cwd(), 'credentials.json')
let myauth = undefined
if (!myauth) {
await authenticate({scopes: SCOPES, keyfilePath: CREDENTIALS_PATH})
.then(client => {
const keys = JSON.parse(fs.readFileSync(CREDENTIALS_PATH))
const key = keys.installed || keys.web
myauth = {
type: 'authorized_user',
client_id: key.client_id,
client_secret: key.client_secret,
refresh_token: client.credentials.refresh_token,
}
console.log(myauth)
})
}
import {google} from 'googleapis'
google.options({auth: google.auth.fromJSON({
type: "authorized_user",
client_id: myauth.client_id
client_secret: myauth.client_secret,
refresh_token: myauth.refresh_token
})})
// Method to fetch tasks from last n days
const tasks = (maxDueDays) => {
const fetchTaskList = (taskList) => taskApi.tasks
.list({
tasklist: taskList.id,
showCompleted: false,
dueMax: dayjs().add(maxDueDays, 'days').format()
})
.then(res => res.data.items.map(task => Object.assign(task, {taskList: taskList.title})))
return taskApi
.tasklists.list()
.then(res => Promise.all(res.data.items.map(fetchTaskList)))
.then(tasks => tasks.flat())
}
tasks(7).then(res => console.log(res))
一段时间后(我每小时轮询一次),我经常会收到以下错误消息:
ERROR 400: {
error: 'invalid_grant',
error_description: 'Token has been expired or revoked.'
}
以下是其他GitHub问题,其中人们遇到了我的问题:
- https://github.com/googleapis/google-api-nodejs-client/issues/1551
- https://github.com/googleapis/google-api-nodejs-client/issues/1907
- https://github.com/googleapis/google-api-nodejs-client/issues/2494
- https://github.com/googleapis/google-api-nodejs-client/issues/2350
- https://github.com/googleapis/google-api-nodejs-client/issues/2834
- https://github.com/googleapis/google-api-nodejs-client/issues/2886
- https://github.com/googleapis/google-api-nodejs-client/issues/1609
- https://github.com/googleapis/google-api-nodejs-client/issues/1450
- https://github.com/googleapis/google-api-nodejs-client/issues/517
- https://github.com/googleapis/google-api-nodejs-client/issues/42
Google是否提供“个人API密钥”,让我可以绕过OAuth流程直接读取自己的数据,因为这个应用程序只用于个人使用?如果不是,是否有一种编程方式来处理令牌过期,而不涉及打开浏览器,因为这在运行在无头嵌入式设备上?Google的示例代码教程似乎并没有处理令牌过期!
英文:
I am developing for a personal embedded device (the Visionect e-ink display) that can run some node.js code to display tasks from my Google Tasks. It works fine but the token expires every so often. How do I handle the token expiry? I cannot show the login screen ofcourse on this e-ink display. How can I permanently have code that works till the user (in this case there is only 1 user - me) revokes the access token?
I looked at this answer but I am not sure it answers my question: https://stackoverflow.com/questions/53786782/google-api-authentication-tasks-api/53787724#53787724
Here is my code:
/*
credentials.json:
{
"installed": {
"client_id": "XXXXXXX.apps.googleusercontent.com",
"project_id": "XXXXXXX",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "XXXXXXX",
"redirect_uris": [
"http://localhost"
]
}
}
*/
import fs from 'fs'
import path from 'path'
import process from 'process'
import {authenticate} from '@google-cloud/local-auth'
const SCOPES = ['https://www.googleapis.com/auth/tasks.readonly']
const CREDENTIALS_PATH = path.join(process.cwd(), 'credentials.json')
let myauth = undefined
if (!myauth) {
await authenticate({scopes: SCOPES, keyfilePath: CREDENTIALS_PATH})
.then(client => {
const keys = JSON.parse(fs.readFileSync(CREDENTIALS_PATH))
const key = keys.installed || keys.web
myauth = {
type: 'authorized_user',
client_id: key.client_id,
client_secret: key.client_secret,
refresh_token: client.credentials.refresh_token,
}
console.log(myauth)
})
}
import {google} from 'googleapis'
google.options({auth: google.auth.fromJSON({
type: "authorized_user",
client_id: myauth.client_id
client_secret: myauth.client_secret,
refresh_token: myauth.refresh_token
)})
// Method to fetch tasks from last n days
const tasks = (maxDueDays) => {
const fetchTaskList = (taskList) => taskApi.tasks
.list({
tasklist: taskList.id,
showCompleted: false,
dueMax: dayjs().add(maxDueDays, 'days').format()
})
.then(res => res.data.items.map(task => Object.assign(task, {taskList: taskList.title})))
return taskApi
.tasklists.list()
.then(res => Promise.all(res.data.items.map(fetchTaskList)))
.then(tasks => tasks.flat())
}
tasks(7).then(res => console.log(res))
After a bit (I poll once a hour), I often get:
ERROR 400: {
error: 'invalid_grant',
error_description: 'Token has been expired or revoked.'
}
Here are some other Github issues where people encountered my problem:
- https://github.com/googleapis/google-api-nodejs-client/issues/1551
- https://github.com/googleapis/google-api-nodejs-client/issues/1907
- https://github.com/googleapis/google-api-nodejs-client/issues/2494
- https://github.com/googleapis/google-api-nodejs-client/issues/2350
- https://github.com/googleapis/google-api-nodejs-client/issues/2834
- https://github.com/googleapis/google-api-nodejs-client/issues/2886
- https://github.com/googleapis/google-api-nodejs-client/issues/1609
- https://github.com/googleapis/google-api-nodejs-client/issues/1450
- https://github.com/googleapis/google-api-nodejs-client/issues/517
- https://github.com/googleapis/google-api-nodejs-client/issues/42
Does Google provide a "personal API key" which let's me just read my own data bypassing the oauth dance since this app is only intended for my personal use? If not, is there a programmatic way to handle token expiry which does not involve opening a browser since this is running on an embedded headless device? Google's own sample code tutorial does not really handle token expiry!
答案1
得分: 1
将您的应用设置为Google Cloud控制台中的生产模式,位于oauth2同意屏幕下,您的刷新令牌将不会过期。
英文:
Set your app to production in google cloud console under the oauth2 consent screen and your refresh token will stop expiring
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论