我的目标
使用OAuth 2将刷新令牌与Google的访问令牌交换。
我的代码
bool Google_Account::Refresh_Access_Token_Using_Refresh_Token()
{
// Prepare Url
QUrl url(tr("https://www.googleapis.com/oauth2/v4/token"));
// Create request
QNetworkRequest request(url);
request.setRawHeader("Host:","www.googleapis.com");
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
// Create request body ClientID, ClientSecret, RefreshTokenString are class data members
QString RequestBody = tr("client_secret=%1&").arg(ClientSecret) +
tr("grant_type=refresh_token&")+
tr("refresh_token=%1&").arg(RefreshTokenString)+
tr("client_id=%1").arg(ClientID);
QByteArray array = RequestBody.toUtf8();
// Get reply
QNetworkReply *reply = mQNAM.post(request, array); // mQNAM is QNetworkAccessManager
// Set timeout to reply while waiting for reply finished
bool stop = false;
QTimer timer;
timer.setSingleShot(true);
QObject::connect(&timer, &QTimer::timeout, [&](){
qDebug()<<"Time out";
stop = true;
});
timer.start(5000);
// Wait till the response is completed
while(!reply->isFinished()){
QCoreApplication::processEvents();
if(stop){
qDebug()<<"Going to abort";
reply->abort();
}
}
// Check for reply
if(reply->isFinished()){
if(reply->error() != QNetworkReply::NoError){
qDebug()<<reply->readAll();
emit setMessage("Error: "+reply->errorString());
delete reply;
return false;
}
else{
QByteArray array = reply->readAll();
QJsonDocument document = QJsonDocument::fromJson(array);
QJsonObject obj = document.object();
access_token = obj.value("access_token").toString(); //access_token is class data variable
delete reply;
return true;
}
}
else{
delete reply;
return false;
}
}
问题是,如果我在Windows 7 pc(Qt 5.11.1)中运行此代码,一切都很好,我会获得访问令牌,但如果我在树莓派(raspbian Qt 5.7)中运行,则会出现错误400,错误来自Google的请求。我尝试使用从Windows PC上获得的access_token并发出其他请求,例如从Google驱动器获取文件列表,它们在树莓派中工作正常,但是只有这个我有问题。我究竟做错了什么? P.S该代码仅重构为特定细节,实际上我是从QSettings获取客户端ID和其他密钥的
答案 0 :(得分:0)
这听起来像是在 Qt 请求令牌时收到 400 代码,因为当流程返回到您的应用程序时您获得的登录代码是 URL 编码的。我们用一些代码示例编写了关于 How To Authenticate with Google SSO in Qt 的内容,包括在流程中注入参数修饰符的这一位:
google->setModifyParametersFunction([](QAbstractOAuth::Stage stage, QVariantMap* parameters) {
// Percent-decode the "code" parameter so Google can match it
if (stage == QAbstractOAuth::Stage::RequestingAccessToken) {
QByteArray code = parameters->value("code").toByteArray();
(*parameters)["code"] = QUrl::fromPercentEncoding(code);
}
});
在初始请求之前执行此操作,但正如上面@Giancarlo 所建议的那样,我会重写您的代码以异步工作。它更简单、更可靠。