2016-04-12 306 views
1

我正在使用google-auth-library-nodejs庫整合到一些GMail帳戶中,以獲取電子郵件列表。Google OAuth2 API刷新令牌

我的處理流程是簡單的:

1)嘗試授權客戶端,使用此功能:

function _authorise(mailBox, callback) { 
    let auth = new googleAuth(); 

    let clientId = eval(`process.env.GMAIL_API_CLIENT_ID_${mailBox.toUpperCase()}`); 
    let clientSecret = eval(`process.env.GMAIL_API_CLIENT_SECRET_${mailBox.toUpperCase()}`); 
    let redirectUri = eval(`process.env.GMAIL_API_REDIRECT_URI_${mailBox.toUpperCase()}`); 
    let tokenFile = process.env.GMAIL_API_TOKEN_PATH + mailBox.toLowerCase()+ process.env.GMAIL_API_TOKEN_BASE_FILE_NAME; 

    let oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUri); 
    fs.readFile(tokenFile, ((err, token) => { 
    if (err) { 
     _getNewToken(mailBox,oauth2Client,callback); 
    } else { 
     oauth2Client.credentials = JSON.parse(token); 
     callback(oauth2Client); 
    } 
    })) 
} 

2)的方法,將檢查在文件中的令牌的存在。如果沒有找到該文件,以下功能將創建文件:

function _getNewToken(mailBox, oauth2Client, callback) { 
    var authUrl = oauth2Client.generateAuthUrl({ 
    access_type: 'offline', 
    scope: process.env.GMAIL_API_SCOPES 
    }); 
    console.log('To authorize this app, please use this url: ', authUrl); 
    var rl = readline.createInterface({ 
    input: process.stdin, 
    output: process.stdout 
    }); 
    rl.question('Enter the code from that page here: ', ((code) => { 
    rl.close(); 
    oauth2Client.getToken(code, function(err, token) { 
     if (err) { 
     console.log('Error while trying to retrieve access token', err); 
     return; 
     } 
     oauth2Client.credentials = token; 
     _storeToken(mailBox,token); 
     callback(oauth2Client); 
    }); 
    })); 
} 

function _storeToken(mailBox, token) { 
    let tokenFile = process.env.GMAIL_API_TOKEN_PATH + mailBox.toLowerCase()+ process.env.GMAIL_API_TOKEN_BASE_FILE_NAME; 
    fs.writeFile(tokenFile, JSON.stringify(token)); 
} 

我使用https://www.googleapis.com/auth/gmail.readonly的範圍。

下面是創建該文件的一個示例:

{"access_token":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","token_type":"Bearer","refresh_token":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","expiry_date":1460509994081} 

在處理的時候,這裏的返回的身份驗證對象的示例:

OAuth2Client { 
    transporter: DefaultTransporter {}, 
    clientId_: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com', 
    clientSecret_: 'xxxxxxxxxxxxxxxxxxxxxxxx', 
    redirectUri_: 'urn:ietf:wg:oauth:2.0:oob', 
    opts: {}, 
    credentials: { 
access_token: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 
    token_type: 'Bearer', 
    refresh_token: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 
    expiry_date: 1460509994081 
    } 
} 

如果我刪除該文件,並辦理手動同意過程,然後驗證工作100%,直到令牌過期。在此之後,我收到「無效憑證」消息。

我的假設是,一旦令牌到期,刷新令牌將用於自動重新創建訪問令牌。我錯過了什麼嗎?

+0

如果您請求訪問該用戶並正在獲取新的令牌,您是否將其保存?你只能使用谷歌25個積極refrestokens後,他們停止工作,你會得到無效的憑據。 – DaImTo

+0

@DaImTo,是的,我懷疑它是25的限制。我不明白的是刷新令牌重新發布的時間。 – go4cas

+0

我剛剛刷新訪問令牌,然後我得到一個新的access_token,一個新的refresh_token和一個新的expiry_date。失效日期有效期爲1小時。所以,我的假設是,在1小時到期窗口後,refresh_token將被用來自動創建一個新的access_token。那是對的嗎?或者1小時後refresh_token還會重新生成嗎? – go4cas

回答

2

好了,我已經發現了getAccessToken方法,它會檢查access_token,並使用它,除非它已經過期,在這種情況下,它會使用refresh_token生成一個新的access_token