Page 1 of 4 1 2 3 ... LastLast
Results 1 to 15 of 55

Thread: Oauth2 rest client Asana

  1. #1

    Question Oauth2 rest client Asana

    Hallo,

    Ik heb een rest koppeling werkend met Asana, deze werkt middels een Personal Access Token. Dit werkt goed, nu wil ik dit omzetten naar Oauth2 omdat er meer gebruikers gebruik van gaan maken en volgens de documentatie word dan aangeraden Oauth2 te gebruiken. https://asana.com/developers/documen...uick-reference

    Dit heb ik deels op orde, de juiste URL stuur ik nu naar Asana, maar ik krijg niet het zelfde terug als met het invoeren in een browser.

    De URL die ik gebruik:
    Code:
    https://app.asana.com/-/oauth_authorize?client_id=s_Asana_Ident&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&state=somerandomstate
    Vul ik deze in in een browser dan krijg ik terug:

    Please copy this code, switch to your application, and paste it there:
    0/xxxxxxxxxxxxxxxxxxxxxxx

    Als ik onderstaande code gebruik, dan krijg ik een ander resultaat .

    Code:
      Try
    //    s_Asana_Auth_EP:= Asana Authenticatie URL
        Params:=('client_id=' + s_Asana_Ident + '&redirect_uri=' + s_Asana_Redirect_EP + '&response_type=code' + '&state=somerandomstate' );
        AsanaOAuthHttp := THTTPSend.Create;
        AsanaOAuthHttp.Sock.CreateWithSSL(TSSLOpenSSL);
        Memo_Send.Text:=s_Asana_Auth_EP + Params;
        AsanaOAuthHttp.HTTPMethod('GET', s_Asana_Auth_EP + Params);
        Memo_Return.Lines.LoadFromStream(AsanaOAuthHttp.Document);
        E_Returncode.Text:=IntToSTR(AsanaOauthHttp.ResultCode);
        Exit;
      Finally
        screen.cursor:=crDefault;
      End; // End Try
    De returncode is 200, dus het lijkt erop dat het geslaagd is, echter krijg ik niet de code terug, de login pagina van Asana.

    <!DOCTYPE html>
    <html>
    <head>
    <title>Asana - Log In</title>

    Hoe kan ik er nu voor zorgen dat de gebruiker automatisch ingelogd wordt?

  2. #2
    Quote Originally Posted by rsjmeijer View Post
    Please copy this code, switch to your application, and paste it there:
    0/xxxxxxxxxxxxxxxxxxxxxxx
    Dat is je Authentication code die je terugkrijgt na toestemming van de gebruiker.
    Zo werkt OAuth 2.0. (heb je de documentatie gelezen over hoe OAuth 2.0 werkt?)

    Je krijgt dus eerst een Authentication code waarmee je een Access token aan kan vragen (en eventueel een Refesh token voor wanneer de Access token verlopen is). Met die tokens krijg je toegang tot de toegestemde delen.

    Even een opmerking over de "urn:ietf:wg:oauth:2.0:oob". Die zorgt er voor dat je Authentication code op het beeldscherm en in de Titel-bar getoond wordt (en dus e.v. gekopieerd en geplakt dient te worden). Je zou dit ook met code af kunnen vangen zodat de gebruiker dit niet zelf in hoeft te geven. Je kunt bij redirect_uri ook een eigen intern adres opgeven en dan met Delphi op dat adres/poort luisteren naar het resultaat. Dan krijg je ook direct de Authentication code in je programma zonder dat de gebruiker dit zelf moet knippen en plakken. (Maar dat zal voor latere zorg zijn nadat je goed kunt werken met de Access/Refresh tokens.)


    Edit: Ik zie dat het op die genoemde pagina eigenlijk ook allemaal duidelijk uitgelegd wordt. Wat jij in jou stukje code mist is de toestemming die de gebruiker moet geven. Jij probeert gewoon die pagina uit te lezen en hoopt dat daar die code in staat. Maar zo gaat dat niet. Een gebruiker moet eerst (eenmalig) inloggen op die pagina en dan krijg je pas die code te zien. En dat inloggen moet echt handmatig (eenmalig) door de gebruiker gebeuren. Dat is de beveiliging. Je moet dus een browser-component openen en de gebruiker in laten loggen en de code afvangen. Of je opent automatisch de standaard browser op de genoemde URL en laat via de redirect_uri verwijzen naar een adres/poort waarop je naar die code luistert.

    Wanneer je uiteindelijk, na de eenmalige toestemming van de gebruiker, de Access en Refresh tokens hebt kun je daarna alles doen zonder de gebruikers toestemming (want die is al gegeven).
    Last edited by rvk; 11-Nov-17 at 22:28.

  3. #3
    Hallo Rik,

    Dank voor je snelle recatie!

    Quote Originally Posted by rvk View Post
    Dat is je Authentication code die je terugkrijgt na toestemming van de gebruiker.
    Zo werkt OAuth 2.0. (heb je de documentatie gelezen over hoe OAuth 2.0 werkt?)
    Ja die heb ik gelezen, en het is bekend dat dat de Authentication code is. Ik had alleen gehoopt dat deze code ook terug werd gegeven in de pagina die terug gestuurd word. Maar dat is wat te voorbarig


    Quote Originally Posted by rvk View Post
    Wat jij in jou stukje code mist is de toestemming die de gebruiker moet geven. Jij probeert gewoon die pagina uit te lezen en hoopt dat daar die code in staat. Maar zo gaat dat niet. Een gebruiker moet eerst (eenmalig) inloggen op die pagina en dan krijg je pas die code te zien. En dat inloggen moet echt handmatig (eenmalig) door de gebruiker gebeuren. Dat is de beveiliging. Je moet dus een browser-component openen en de gebruiker in laten loggen en de code afvangen. Of je opent automatisch de standaard browser op de genoemde URL en laat via de redirect_uri verwijzen naar een adres/poort waarop je naar die code luistert.
    Begrijp ik goed dat het inloggen niet automatisch kan?

    groeten Robert

  4. #4
    Quote Originally Posted by rsjmeijer View Post
    Begrijp ik goed dat het inloggen niet automatisch kan?
    Yup, dat begrijp je goed.

    Zoals je ziet krijg je zelf ook met je HTTPMethod/GET een login pagina terug. Normaal zou je die pagina dus in een browser krijgen. Een gebruiker MOET altijd inloggen en krijgt dan een toestemming-scherm waarin die op JA moet klikken.

    Let wel, dit is slechts een éénmalige actie. Op het moment dat je eenmaal die Authentication code hebt kun je in code de tokens aanvragen en is er geen tussenkomst van de gebruiker meer nodig. Nooit meer. De Access-token kan op een gegeven moment verlopen maar dan kun je met de Refresh-token weer een nieuwe Access-token aanvragen.

    Jij had het er ook over dat er meer gebruikers mee gaan werken. Ik neem niet aan dat je de wachtwoorden van die gebruikers zou krijgen. Vandaar dat die eenmalige (handmatige) toestemming de enige manier is om toegang tot hun gegevens te krijgen.

  5. #5
    Ok, dank zover, ik ga nog eens stoeien!

  6. #6
    Ik heb de module met Asana werkt, nu is Exact de uitdaging.

    Het authenticatie gedeelte heb ik werkend, alleen krijg ik het maar niet voor elkaar de token toegestuurd te krijgen.

    Ik gebruik onderstaande code, probleem is dat het lijkt alsof de URL dubbel word gecodeerd (

    Delphi Code:
    1. Try
    2.  // Code volgens Exact developer website
    3.  {
    4.    code: “XTzM!IAAAACbPTzQJXwFhM”,
    5.    redirect_uri: [url]https://www.mycompany.com/myapplication[/url]
    6.    grant_type: “authorization_code”,
    7.    client_id: “b81cc4de-d192-400e-bcb4-09254394c52a”,
    8.    client_secret: “n3G7KAhcv8OH”
    9.  }
    10.  
    11.    Params:=('code=' + EncodeURIComponent(e_ReceiveCode.Text) +
    12.             '&redirect_uri=' + EncodeURIComponent(s_Exact_Redirect_EP) +
    13.             '&grant_type=' + EncodeURIComponent('authorization_code') +
    14.             '&client_id={' + EncodeURIComponent(s_Exact_Ident) +
    15.             '}&client_secret=' + EncodeURIComponent(s_Exact_Secret));
    16.  
    17.     Memo_Send.Text:=s_Exact_Token_EP + Params;
    18.     AsanaBrowser.Navigate(s_Exact_Token_EP + Params);
    19.     AsanaOAuthHttp := THTTPSend.Create;
    20.     AsanaOAuthHttp.Sock.CreateWithSSL(TSSLOpenSSL);
    21.     AsanaOAuthHttp.HTTPMethod('POST', EncodeURLElement(s_Exact_Token_EP) + Params);
    22.     Memo_Return.Lines.LoadFromStream(AsanaOAuthHttp.Document);
    23.     E_Returncode.Text:=IntToSTR(AsanaOauthHttp.ResultCode);
    24.   Finally
    25.     AsanaOAuthHttp.Clear;
    26.     AsanaOAuthHttp.Destroy;
    27.     screen.cursor:=crDefault;
    28.   End; // End Try

    Ik krijg terug Bad Request.

    Wat mij opvalt is dat de redirect url er als volgt uitziet: &redirect_uri=http%3a%2f%2flocalhost%3a8080 Dit lijkt op het probleem wat hier staat omschreven: http://www.nldelphi.com/showthread.p...-tidhttp/page3
    En dan de 7e melding.

    Wat mij dus opvalt is dat indy DUBBEL encoding doet.

    Er zit in je IdHTTP component een property HTTPOptions.
    Zet daarin de hoForceEncodeParams eens uit !!!


    Ik heb me suf gezocht, maar ik kan niet achterhalen hoe de optie van Indy (hoForceEncodeParams) bij httpsend.

    Wie kan mij verder helpen?

  7. #7
    Mmm, ik begrijp niet helemaal wat je met die code wilt doen.

    Wat is AsanaBrowser?
    Je schijnt te navigeren met die AsanaBrowser maar direct daarna doe je ook een POST met HTTPMethod.

    Wat wil je daarmee bereiken?

    Ik had al aangegeven dat je die navigate dus moet gebruiken om de toestemming van de gebruiker te vragen. Je doet dan verder helemaal geen POST. Je moet een HTTPServer opzetten (of uitluisteren op een poort) en dan krijg je vanzelf daar die token op terug.

    Dus wat doet ie AsanaOAuthHttp.HTTPMethod nu nog in jouw code.
    (want het is logisch dat je daar een Bad Request op krijgt want die accepteert helemaal geen POST op die manier.)

  8. #8
    Ik gebruik voor Google OAuth2 dit stukje als "Server" om op localhost te luisteren naar de authentication code.

    (maakt gebruik van synapse)
    Delphi Code:
    1. uses
    2.   synacode, synautil, httpsend, // for communication
    3.   ssl_openssl, // you need to include this one in your requirements
    4.  
    5. type
    6.   THTTPServerThread = class(TThread)
    7.   private
    8.     ListenerSocket: TTCPBlockSocket;
    9.     ConnectionSocket: TTCPBlockSocket;
    10.   public
    11.     Authorize_token: String;
    12.     procedure Execute; override;
    13.     procedure CancelThread(Sender: TObject; var CanClose: Boolean);
    14.   end;
    15.  
    16. procedure THTTPServerThread.CancelThread(Sender: TObject; var CanClose: Boolean);
    17. begin
    18.   Terminate;
    19. end;
    20.  
    21. procedure THTTPServerThread.Execute;
    22. var
    23.   S: string;
    24.   method, uri, protocol: string;
    25.   OutputDataString: string;
    26. begin
    27.   Authorize_token := '';
    28.   FreeOnTerminate := False;
    29.   ListenerSocket := TTCPBlockSocket.Create;
    30.   ConnectionSocket := TTCPBlockSocket.Create;
    31.  
    32.   try
    33.     ListenerSocket.CreateSocket;
    34.     ListenerSocket.setLinger(True, 10);
    35.     ListenerSocket.Bind('localhost', '1500');
    36.     ListenerSocket.Listen;
    37.     while not terminated do
    38.     begin
    39.       Sleep(1000);
    40.       Application.ProcessMessages;
    41.       if ListenerSocket.CanRead(1000) and not Terminated then
    42.       begin
    43.         ConnectionSocket.Socket := ListenerSocket.Accept;
    44.  
    45.         // read request line
    46.         S := string(ConnectionSocket.RecvString(1000));
    47.         method := fetch(S, ' ');
    48.         uri := fetch(S, ' ');
    49.         protocol := fetch(S, ' ');
    50.  
    51.         // read request headers
    52.         repeat
    53.             S := string(ConnectionSocket.RecvString(1000));
    54.         until S = '';
    55.  
    56.         // /?code=4/fegArZQDUJqFdoCw-1DU16ohYsoA5116feRuCW0LiuQ
    57.         // /?error=access_denied
    58.         Authorize_token := '';
    59.         if Pos('code=', uri) > 0 then
    60.         begin
    61.           Authorize_token := Copy(uri, Pos('code=', uri) + 5);
    62.         end;
    63.  
    64.         OutputDataString := 'HTTP/1.0 200' + CRLF;
    65.         OutputDataString := OutputDataString + 'Content-type: Text/Html' + CRLF;
    66.         OutputDataString := OutputDataString + 'Content-length: ' + IntTostr(Length(OutputDataString)) + CRLF;
    67.         OutputDataString := OutputDataString + 'Connection: close' + CRLF;
    68.         OutputDataString := OutputDataString + 'Date: ' + Rfc822DateTime(now) + CRLF;
    69.         OutputDataString := OutputDataString + 'Server: Ciswin Synapse' + CRLF;
    70.         OutputDataString := OutputDataString + '' + CRLF;
    71.         ConnectionSocket.SendString(ansistring(OutputDataString));
    72.         // if ASocket.lasterror <> 0 then HandleError;
    73.  
    74.         if Authorize_token = '' then
    75.         begin
    76.           OutputDataString :=
    77.             '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'
    78.             + ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' + CRLF
    79.             + '<html><center><h1>Er is iets mis gegaan.<br><br>Cis heeft GEEN toegang.<br><br>U kunt deze pagina sluiten.</h1></center></html>' + CRLF;
    80.         end
    81.         else
    82.         begin
    83.           OutputDataString :=
    84.             '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'
    85.             + ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' + CRLF
    86.             + '<html><center><h1>Cis heeft nu toegang.<br><br>U kunt deze pagina sluiten.</h1></center></html>' + CRLF;
    87.         end;
    88.         ConnectionSocket.SendString(ansistring(OutputDataString));
    89.  
    90.         ConnectionSocket.CloseSocket;
    91.  
    92.         Terminate;
    93.       end;
    94.     end;
    95.  
    96.   finally
    97.     ConnectionSocket.Free;
    98.     ListenerSocket.Free;
    99.   end;
    100.  
    101. end;
    102.  
    103. procedure TGoogleOAuth2.GetAuthorize_token_interactive;
    104. var
    105.   URL: string;
    106.   Params: string;
    107.   GoUrl: variant;
    108.   Scope: string;
    109.   ServerThread: THTTPServerThread;
    110.   dl: TForm;
    111.  
    112.   function StartBrowser(const FileName: string): boolean;
    113.   begin
    114.     Result := Shellapi.ShellExecute(0, nil, pchar(FileName), nil, nil, 5 { SW_SHOW } ) > 32;
    115.   end;
    116.  
    117. begin
    118.   try
    119.  
    120.     Scope := FScopes.DelimitedText;
    121.     if Scope = '' then
    122.     begin
    123.       LogLine('No scope specified in GetAccess');
    124.     end;
    125.  
    126.     URL := AuthorizationUrl;
    127.     Params := '';
    128.     Params := Params + 'response_type=' + EncodeURLElement('code');
    129.     Params := Params + '&client_id=' + EncodeURLElement(FClient_id);
    130.     Params := Params + '&redirect_uri=' + EncodeURLElement(RedirectUri);
    131.     Params := Params + '&scope=' + EncodeURLElement(Scope);
    132.  
    133.     LogLine('Authorizing...');
    134.     GoUrl := URL + '?' + Params;
    135.  
    136.     ServerThread := THTTPServerThread.Create(False);
    137.     try
    138.       StartBrowser(GoUrl); // open website
    139.  
    140.       dl := CreateMessageDialog('Wachten op toestemming', mtInformation, []);
    141.       try
    142.  
    143.         dl.Height := Round(80 * (dl.PixelsPerInch / 96));
    144.         dl.OnCloseQuery := ServerThread.CancelThread;
    145.         dl.Top := 38;
    146.         dl.Left := 5;
    147.         dl.Show;
    148.         dl.Repaint;
    149.  
    150.         while not ServerThread.Terminated do
    151.         begin
    152.           Sleep(1);
    153.           Application.ProcessMessages;
    154.         end;
    155.  
    156.         ServerThread.WaitFor; // blocking met dialog
    157.  
    158.       finally
    159.         dl.Free;
    160.       end;
    161.  
    162.       Authorize_token := ServerThread.Authorize_token;
    163.     finally
    164.       ServerThread.Free;
    165.     end;
    166.  
    167.   except
    168.     // on E: EOleSysError do ;
    169.     on E: Exception do
    170.     begin
    171.       DebugLine('Browser closed without confirmation.');
    172.       DebugLine('Exception: ' + E.Message);
    173.     end;
    174.   end;
    175. end;

  9. #9
    Quote Originally Posted by rvk View Post

    Wat is AsanaBrowser?
    Dat is een TWebBrowser, die hoorde daar inderdaad niet thuis

    Quote Originally Posted by rvk View Post
    Ik had al aangegeven dat je die navigate dus moet gebruiken om de toestemming van de gebruiker te vragen. Je doet dan verder helemaal geen POST. Je moet een HTTPServer opzetten (of uitluisteren op een poort) en dan krijg je vanzelf daar die token op terug.
    De Authenticatie code krijg ik netjes terug, dat werkt wel (maar volgens mij is die aanvraag ongecodeerd). Het verkrijgen van de token lukt via Exact niet.

  10. #10
    Dan begrijp ik het niet.
    Het stukje code dat jij laat zien is om de Authenticatie code terug te krijgen.
    Want de redirect_uri en grant type is juist bedoeld om die Authenticatie code te krijgen.

    Om daarna met de Authenticatie code een access token en refresh token te krijgen moet je een hele andere uri opbouwen.

  11. #11
    Quote Originally Posted by rvk View Post
    Dan begrijp ik het niet.
    Het stukje code dat jij laat zien is om de Authenticatie code terug te krijgen.
    Want de redirect_uri en grant type is juist bedoeld om die Authenticatie code te krijgen.

    Om daarna met de Authenticatie code een access token en refresh token te krijgen moet je een hele andere uri opbouwen.
    Hmmm, als ik kijk op de developer site van Exact staat daar over het verkrijgen van de authenticatiecode:

    HTML Code:
    https://support.exactonline.com/community/s/knowledge-base?language=en_GB#All-All-DNO-Content-oauth-eol-oauth-dev-step2
    Samengevat:
    HTML Code:
    GET https://start.exactonline.nl/api/oauth2/auth?client_id=b81cc4de-d192-400e-bcb4-09254394c52a&redirect_uri=https%3A%2F%2Fwww.mycompany.com%2Fmyapplication&response_type=code&force_login=0
    Dat deel heb ik werkende, ik krijg netjes een authenticatiecode terug van Exact, deze moet ik terug sturen voor een Token volgens de handleiding:
    HTML Code:
    https://support.exactonline.com/community/s/knowledge-base?language=en_GB#All-All-DNO-Content-oauth-eol-oauth-dev-step3
    Hier staat:
    Example

    HTML Code:
    POST ../api/oauth2/token with post data:
    (Post data should be x-www-form-urlencoded)
    
    { 
       code: “XTzM!IAAAACbPTzQJXwFhM”, 
       redirect_uri: https://www.mycompany.com/myapplication 
       grant_type: “authorization_code”, 
       client_id: “b81cc4de-d192-400e-bcb4-09254394c52a”, 
       client_secret: “n3G7KAhcv8OH” 
    {
    Of begrijp ik het verkeerd? Met de API van Asana werkt het goed, maar met Exact krijg ik het niet werkende. Maar zal vast iets over het hoofd zien.

  12. #12
    O, je hebt inderdaad gelijk. De redirect_uri en grant type worden ook bij Google meegegeven voor de access-token.

    Maar ik zie twee mogelijke problemen.
    Wat is s_Exact_Token_EP bij jou?
    Je plakt daar de params direct achteraan. Dat lijkt mij niet goed.

    Verder heb je { } om de client_id staan. Dat zie ik bij het exact voorbeeld niet.

  13. #13
    S_exact_token_ep is de URL voor de token aanvraag incl het ? Teken:
    https://start.exactonline.nl/api/oauth2/token?
    De haakjes om de clientid staan niet in het Exact voorbeeld maar wel in een eerdere item hierover waar je ook bij hebt geholpen van iemand anders. Ik heb ze er wel in staan in de code

  14. #14
    Zoals ik het zie POST je ook die data niet. Je plakt ze gewoon in de URL erachter en dat wordt door de server niet geaccepteerd.

    In Synapse is het zoiets:
    Delphi Code:
    1. Params := '';
    2.   Params := Params + 'code=' + EncodeURLElement(Authorize_token);
    3.   Params := Params + '&client_id=' + EncodeURLElement(FClient_id);
    4.   Params := Params + '&client_secret=' + EncodeURLElement(FClient_secret);
    5.   Params := Params + '&redirect_uri=' + EncodeURLElement(RedirectUri);
    6.   Params := Params + '&grant_type=' + EncodeURLElement('authorization_code');
    7.   Response := TMemoryStream.Create;
    8.   try
    9.     if HttpPostURL(URL, Params, Response) then
    10.     begin
    11.       Response.Position := 0;
    Die params worden dan ook echt als een form-data gePOST.

  15. #15
    Dank zover!! Ik ga aan de slag met je code, eens kijken of dat werkt.

Page 1 of 4 1 2 3 ... LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •