[英]Google Authentication Token return doesn't contain refresh_token
我寫了一個關於谷歌api使用的例子。 Google NodeJS客戶端庫 。 我已經遵循指令集access_type : 'offline'
,但是對象返回不包含refresh_token
。
我的代碼:
var http = require('http');
var express = require('express');
var Session = require('express-session');
var google = require('googleapis');
var plus = google.plus('v1');
var OAuth2 = google.auth.OAuth2;
const ClientId = "251872680446-rvkcvm5mjn1ps32iabf4i2611hcg086e.apps.googleusercontent.com";
const ClientSecret = "F1qG9fFS-QwcrEfZbT8VmUnx";
const RedirectionUrl = "http://localhost:8081/oauthCallback";
var app = express();
app.use(Session({
secret: 'raysources-secret-19890913007',
resave: true,
saveUninitialized: true
}));
function getOAuthClient () {
return new OAuth2(ClientId , ClientSecret, RedirectionUrl);
}
function getAuthUrl () {
var oauth2Client = getOAuthClient();
// generate a url that asks permissions for Google+ and Google Calendar scopes
var scopes = [
'https://www.googleapis.com/auth/plus.me'
];
var url = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: scopes // If you only need one scope you can pass it as string
});
return url;
}
app.use("/oauthCallback", function (req, res) {
var oauth2Client = getOAuthClient();
var session = req.session;
var code = req.query.code;
oauth2Client.getToken(code, function(err, tokens) {
console.log("tokens : ", tokens);
// Now tokens contains an access_token and an optional refresh_token. Save them.
if(!err) {
oauth2Client.setCredentials(tokens);
session["tokens"]=tokens;
res.send(`
<html>
<body>
<h3>Login successful!!</h3>
<a href="/details">Go to details page</a>
<body>
<html>
`);
}
else{
res.send(`
<html>
<body>
<h3>Login failed!!</h3>
</body>
</html>
`);
}
});
});
app.use("/details", function (req, res) {
var oauth2Client = getOAuthClient();
oauth2Client.setCredentials(req.session["tokens"]);
var p = new Promise(function (resolve, reject) {
plus.people.get({ userId: 'me', auth: oauth2Client }, function(err, response) {
console.log("response : " , response);
resolve(response || err);
});
}).then(function (data) {
res.send(`<html><body>
<img src=${data.image.url} />
<h3>Hello ${data.displayName}</h3>
</body>
</html>
`);
})
});
app.use("/", function (req, res) {
var url = getAuthUrl();
res.send(`
<html>
<body>
<h1>Authentication using google oAuth</h1>
<a href=${url}>Login</a>
</body>
</html>
`)
});
var port = 8081;
var server = http.createServer(app);
server.listen(port);
server.on('listening', function () {
console.log(`listening to ${port}`);
});
刷新令牌僅在用戶首次批准您指定的范圍后登錄到您的應用程序時發送。
編輯08/2018 :使用approval_prompt:'force'
不再有效,您需要使用prompt:'consent'
(查看@ Alexander的回答)
如果您希望每次用戶登錄時獲取刷新令牌(即使用戶之前已經登錄並批准了作用域),您必須在Oauth2Client
配置中指定prompt:'consent'
:
var url = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: scopes,
prompt : 'consent'
});
請注意,這將要求用戶在每次單擊您的鏈接進行身份驗證時接受指定的范圍:
您還可以在帳戶權限設置中手動禁用應用程序,這將撤消應用程序,並且用戶必須再次接受范圍,這將觸發下次進行身份驗證時發送的refresh_token
:
僅供參考,如果您需要脫機使用access_token
,則必須存儲refresh_token
服務器端,並在從Google API收到狀態401時使用存儲的refresh_token
刷新access_token。 因此,如果您按原樣存儲refresh_token
,則實際上不需要使用prompt:'consent'
並強制用戶在每次連接到您的應用程序時批准范圍。
根據文檔 ,refresh_token僅在第一次授權時返回。
您可以手動刪除權限: https : //myaccount.google.com/permissions
您也可以通過在授權URL中傳遞&prompt = consent來強制用戶再次查看同意屏幕,只需添加以下參數:
var url = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: scopes,
prompt: 'consent'
});
它對我來說很好:)
在某些情況下(主要是Web客戶端),刷新令牌僅在用戶第一次進行身份驗證時發送。
如果您轉到與帳戶關聯的應用,請移除相關應用。 然后嘗試再次驗證。 檢查,現在應該有一個刷新令牌。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.