使用google oauth2库,我可以在用户第一次通过时成功地对其进行身份验证,获得他们的刷新令牌和第一次访问令牌。直到令牌过期,一切都按预期工作。
但是,当访问令牌过期时,我需要获得一个新的访问令牌,并使用现有的刷新令牌将这些令牌存储在我的数据存储区中。我知道文档中规定了令牌过期时应该重新提取它们自己,但是当我为每个调用创建一个新客户机(以确保令牌不会在用户之间重用)时,我认为客户机在令牌有机会刷新自己之前就已经被拆除了。
检查库调用实际的google api时,我应该能够通过调用client.refreshAccessStoken()
方法获得新的访问令牌,这个调用的响应会给出invalid_grant
bad request
错误。我将这个方法发出的实际api请求与google oauth2 playground上的api请求进行了比较,这两个调用是相同的--尽管它们刷新令牌的调用有效,而我的调用不有效。
附上的是我的代码,因为它现在目前的立场,请发送帮助-我没有任何头发留下拔出!
const { google } = require('googleapis')
const scopes = [
'https://www.googleapis.com/auth/spreadsheets.readonly',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/drive.readonly'
]
module.exports = (env, mongo) => {
const getBaseClient = () => {
const { OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, OAUTH_CALLBACK_URL } = env.credentials
return new google.auth.OAuth2(
OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, OAUTH_CALLBACK_URL
)
}
const getNewAccessTokens = async (authId, refreshToken) => {
const { tokens } = await getBaseClient().getToken(refreshToken)
await mongo.setAccessTokensForAuthUser(authId, { ...tokens, refresh_token: refreshToken })
return tokens
}
const getAuthedClient = async (authId) => {
let tokens = await mongo.getAccessTokensForAuthUser(authId)
if (!tokens.access_token) {
tokens = await getNewAccessTokens(authId, tokens.refresh_token)
}
const client = getBaseClient()
client.setCredentials(tokens)
if (client.isTokenExpiring()) {
const { credentials } = await client.refreshAccessToken()
tokens = { ...credentials, refresh_token: tokens.refreshToken }
await mongo.setAccessTokensForAuthUser(authId, tokens)
client.setCredentials(tokens)
}
return client
}
const generateAuthUrl = (userId) => {
return getBaseClient().generateAuthUrl({
access_type: 'offline',
scope: scopes,
state: `userId=${userId}`
})
}
const getUserInfo = async (authId) => {
const auth = await getAuthedClient(authId)
return google.oauth2({ version: 'v2', auth }).userinfo.get({})
}
const listSheets = async (authId) => {
const auth = await getAuthedClient(authId)
let nextPageToken = null
let results = []
do {
const { data } = await google
.drive({ version: 'v3', auth })
.files.list({
q: 'mimeType = \'application/vnd.google-apps.spreadsheet\'',
includeItemsFromAllDrives: true,
supportsAllDrives: true,
corpora: 'user',
orderBy: 'name',
pageToken: nextPageToken
})
nextPageToken = data.nextPageToken
results = results.concat(data.files)
} while (nextPageToken)
return results
}
return {
generateAuthUrl,
getUserInfo,
listSheets
}
}
我解决了自己的问题。
我将access_codes
与refresh_tokens
混为一谈,认为从auth url接收的代码是refresh_token,存储它,并试图重用它以获得更多access_tokens
。这是不对的。别这样。
您从身份验证url获得access_code
,当您第一次将其与client.getToken(code)
方法一起使用时,您将收到refresh_token
和access_token
。
我还应该提到的是,我在auth url中添加了提示符:'consession'
,这样当有人重新进行身份验证时,您总是可以收到access_code
,您可以使用该access_code来获取refresh_token
(如果您没有进行身份验证,那么调用client.gettoken()
不会返回
const { google } = require('googleapis')
const scopes = [
'https://www.googleapis.com/auth/spreadsheets.readonly',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/drive.readonly'
]
module.exports = (env, mongo) => {
const getBaseClient = () => {
const { OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, OAUTH_CALLBACK_URL } = env.credentials
return new google.auth.OAuth2(
OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, OAUTH_CALLBACK_URL
)
}
const getAuthedClient = async (authId) => {
let tokens = await mongo.getAccessTokensForAuthUser(authId)
const client = getBaseClient()
client.setCredentials(tokens)
if (client.isTokenExpiring()) {
const { credentials } = await client.refreshAccessToken()
tokens = { ...credentials, refresh_token: tokens.refresh_token }
await mongo.setAccessTokensForAuthUser(authId, tokens)
client.setCredentials(tokens)
}
return client
}
const generateAuthUrl = (userId) => {
return getBaseClient().generateAuthUrl({
access_type: 'offline',
prompt: 'consent',
scope: scopes,
state: `userId=${userId}`
})
}
const getUserInfo = async (accessCode) => {
const auth = getBaseClient()
const { tokens } = await auth.getToken(accessCode)
auth.setCredentials(tokens)
const { data } = await google.oauth2({ version: 'v2', auth }).userinfo.get({})
return { ...data, tokens }
}
const listSheets = async (authId) => {
const auth = await getAuthedClient(authId)
let nextPageToken = null
let results = []
do {
const { data } = await google
.drive({ version: 'v3', auth })
.files.list({
q: 'mimeType = \'application/vnd.google-apps.spreadsheet\'',
includeItemsFromAllDrives: true,
supportsAllDrives: true,
corpora: 'user',
orderBy: 'name',
pageToken: nextPageToken
})
nextPageToken = data.nextPageToken
results = results.concat(data.files)
} while (nextPageToken)
return results
}
return {
generateAuthUrl,
getUserInfo,
listSheets
}
}
目前访问类型处于联机状态。当我需要访问驱动器上的文件/文件夹时,我将浏览器重定向到Google URL并获得访问代码: 一切运转良好!但我只需要第一次重定向。 当我谷歌时,在google Drive API文档中,我发现我可以通过浏览器重定向获得刷新令牌,并将其保存在数据库中。(换句话说,我可以使用脱机访问)。 而且每次当我需要从google drive读取数据时,我使用刷新令牌获得访问令牌,而无
我的问题是如何使用OAuth2.0从刷新令牌中获取访问令牌。我还没有找到任何从刷新令牌中获取访问令牌的例子。 我参考了[Google+API参考],但他们使用HTTP方法提到了它。2请用C#提供一些使用Google+API提供的方法的例子。
我如何从第一次授权代码中获得刷新令牌和访问令牌?并且,我如何重用这个刷新令牌来获得一个新的访问令牌,以便使用Java API上传到Google Drive?这不是一个web应用程序。它在Java Swing代码中。
我正在使用Cognito用户池对系统中的用户进行身份验证。成功的身份验证将提供一个ID令牌(JWT)、一个访问令牌(JWT)和一个刷新令牌。这里的文档清楚地提到了刷新令牌可以用于刷新访问令牌,但没有提到如何使用。我的问题是,一旦我的访问令牌过期,我如何使用存储的刷新令牌再次刷新我的访问令牌? 我搜索了JavaScript SDK,但找不到任何方法来做同样的事情。我肯定错过了什么。 我还想通过Lam
我编写了一个控制台ASP.NET应用程序来获取AccessTokens。我有clientId,我的应用程序的客户端秘密,我做了以下操作: var authContext=新的AuthenticationContext(“https://login.windows.net/common/oauth2/authorize”);var acquireTask=authContext.AcquireTok