4
votes

I must be missing something here!

I have been playing around trying to refresh an expired OAUTH2 token using the new ( new to me anyway, coming from delphi xe2 environment) TOAuth2Authenticator, TRESTClient, TRESTRequest, TRESTResponse components

I have set the following authenticator properties with the existing known values for

  • ClientID
  • ClientSecret
  • Scope
  • AccessTokenEndPoint
  • AuthorizationEndPoint
  • RedirectionEndPoint
  • AccessToken
  • AccessTokenExpiry
  • RefreshToken

and can successful access resources from the REST server, up until the token expires.

I presumed (wrongly, so it seems) if I try an execute a request against a server, and the token had expired, there should be enough detail for the component to realise the token has expired and refresh it as and when it need to.

I take it there is no hidden/undocumented "RefreshExpiredToken" method that I can call?

Any pointers in the right direction would be greatly appreciated :-)

Thanks

1

1 Answers

1
votes

I eventually figured this out, by bastardising the publicTOAuth2Authticator.ChangeAuthCodeToAccessToken procedure, but thought I'd post my solution just in case it helps anyone else out:

LClient := TRestClient.Create(AccessTokenURI);
try
  LRequest := TRESTRequest.Create(LClient); // The LClient now "owns" the Request and will free it.
  LRequest.Method := TRESTRequestMethod.rmPOST;
  LSecretBase64 := String(SZFullEncodeBase64(AnsiString(<myClientID>+ ':' + <MyClientSecret>)));

  LRequest.AddAuthParameter('grant_type', 'refresh_token', TRESTRequestParameterKind.pkGETorPOST);
  LRequest.AddAuthParameter('refresh_token', _AccessRefreshToken, TRESTRequestParameterKind.pkGETorPOST);
  LRequest.AddAuthParameter('Authorization','Basic '+LSecretBase64, TRESTRequestParameterKind.pkHTTPHEADER, [TRESTRequestParameterOption.poDoNotEncode]  );


  LRequest.Execute;
  //Memo1.Lines.Add(LRequest.Response.Content);

  if LRequest.Response.GetSimpleValue('access_token', LToken) then
  begin
    _AccessToken := LToken;
  end;

  if LRequest.Response.GetSimpleValue('refresh_token', LToken) then
  begin
    _AccessRefreshToken := LToken;
    //Memo1.Lines.Add('RefreshExpiredToken: New Refresh Token Extracted');
  end;

  // detect token-type. this is important for how using it later
  if LRequest.Response.GetSimpleValue('token_type', LToken)
   then _TokenType := OAuth2TokenTypeFromString(LToken);

  // if provided by the service, the field "expires_in" contains
  // the number of seconds an access-token will be valid
  if LRequest.Response.GetSimpleValue('expires_in', LToken) then
  begin
    LIntValue := StrToIntdef(LToken, -1);
    if (LIntValue > -1) then
      _AccessTokenExpireDT := IncSecond(Now, LIntValue)
    else
      _AccessTokenExpireDT := 0.0;

    //Memo1.Lines.Add('RefreshExpiredToken: New Token Expires '+formatdatetime('hh:nn:ss dd/mm/yyyy', _AccessTokenExpireDT));
  end;


finally
  LClient.DisposeOf;
end;