2017-02-02 2 views
2

Я работаю с Google Контактами, и все идет хорошо. Но через час я вручную должен обновить предоставленный доступ. В соответствии с этим SO question я должен быть в состоянии обновить refresh_token с этим вызовом:Срок годности контактов Google:

refresh_token = requests.post(
    'https://accounts.google.com/o/oauth2/token', 
    data={ 
     'client_id': APP_ID, 
     'client_secret': APP_SECRET, 
     'refresh_token': refresh_token, 
     'grant_type': 'refresh_token', 
    } 
) 

который я перевел на этот Delphi код

var 
    Http: TidHttp; 
    URLString: string; 
    Req, Resp: TStringStream; 
begin 
    Http := TidHttp.Create(nil); 
    try 
    URLString := 'client_id=' + FGoggleContacts.ClientID; 
    URLString := URLString + '&client_secret=' + FGoggleContacts.ClientSecret; 
    URLString := URLString + '&refresh_token=' + FGoggleContacts.RefreshToken; 
    URLString := URLString + '&grant_type=refresh_token'; 

    Req := TStringStream.Create(URLString); 
    Resp := TStringStream.Create(''); 
    HTTP.DoRequest(Id_HTTPMethodPost, 'https://accounts.google.com/o/oauth2/token', Req, Resp, []); 

    finally 
    Req.Free; 
    Resp.Free; 
    Http.Free; 
    end;  
end; 

но при вызове его я получаю сообщение об ошибке http/1.1 400 bad request

Итак, кратко, как я могу поддерживать связь с Google вживую?

UPDATE

С помощью @ mjn42 я обнаружил, что не хватало Content-Type в моей просьбе. Так что я написал новый метод, чтобы обновить свои символы:

procedure TGContacts.RefreshTokens; 
var 
    Http: TidHttp; 
    URLString: string; 
    Req, Resp: TStringStream; 
    JSon: ISuperObject; 
begin 
    Http := TidHttp.Create(nil); 
    Req := TStringStream.Create(''); 
    Resp := TStringStream.Create(''); 
    try 
    URLString := 'client_id=' + FClientID; 
    URLString := URLString + '&client_secret=' + FClientSecret; 
    URLString := URLString + '&refresh_token=' + FRefreshToken; 
    URLString := URLString + '&grant_type=refresh_token'; 
    Req.WriteString(URLString); 

    HTTP.Request.ContentType := 'application/x-www-form-urlencoded'; 
    HTTP.DoRequest(Id_HTTPMethodPost, 'https://accounts.google.com/o/oauth2/token', Req, Resp, []); 
    if HTTP.ResponseCode = 200 then 
    begin 
     JSon := SO(UTF8Decode(Resp.DataString)); 
     FAccessToken := JSon['access_token'].AsString; 
     if JSon['refresh_token'] <> nil then 
     FRefreshToken := JSon['refresh_token'].AsString; 
    end; 

    finally 
    Req.Free; 
    Resp.Free; 
    Http.Free; 
    end; 
end; 

Я просто называю это перед обращением к API, то маркеры не истечет.

+1

ли Content-Type: применение/х-WWW-form- urlencoded в заголовке запроса? – mjn42

+1

@ mjn42 спасибо, что сделал трюк –

ответ

2

Согласно спецификации на https://tools.ietf.org/html/rfc6749#section-6 запрос должен использовать Content-Type: применение/х-WWW-форм-urlencoded:

POST /token HTTP/1.1 
Host: server.example.com 
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW 
Content-Type: application/x-www-form-urlencoded 

grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA 
+0

Спасибо Я добавил HTTP.Request.ContentType: = 'application/x-www-form-urlencoded'; к моему коду delphi, и теперь он больше не подводит. Но мой токен все еще истекает через час! –

+0

Что возвращает запрос (статус, тело)? – mjn42

+0

Я провел еще несколько тестов, и я получил его на работу. Благодаря вам. –

Смежные вопросы