Ankündigung

Einklappen
Keine Ankündigung bisher.

Cookies im cURL-Request mitsenden

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Cookies im cURL-Request mitsenden

    Hallo,

    ich habe zwei Symfony Applikationen, App1, eine "öffentliche" API, ist nach außen hin offen, App2 benötigt einen eingeloggten Benutzer. Dadurch, dass beides separate Apps sind, kann ich nicht von App1 direkt auf App2 zugreifen, weshalb ich dies per cURL machen möchte.

    Als API call (also nicht im Browser) wird in App1 eine Action "updateUserDetails" zum Einloggen eines Benutzers aufgerufen, um dann im Anschluss per cURL in App2 eine Action "updateUser". Da ich für App2 einen eingeloggten Benutzer brauche, muss ich diesem cURL-Request die Cookies des Logins mitgeben. Allerdings bekomme ich das nicht hin, sondern erhalte stattdessen immer die Rückmeldung "Benutzer nicht eingeloggt" von App2 als Antwort.

    Ich habe schon diverse Lösungen ausprobiert, die ich im Netz gefunden habe, allerdings hat keine funktioniert.

    PHP-Code:
    $cookie_file_path __DIR__."/cookie.txt";

    $curl_handle curl_init();
    $body_json json_encode(array('vorname' => '..''nachname' => '..',...));
    $options = array(
        
    CURLOPT_URL => 'https://my.example.com/app2.php/updateUser/index',
        
    CURLOPT_CUSTOMREQUEST => 'POST',
        
    CURLOPT_POSTFIELDS => $body_json,

        
    CURLOPT_USERAGENT => "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7",

        
    CURLOPT_VERBOSE => true,
        
    CURLOPT_RETURNTRANSFER => true,    
        
    CURLOPT_COOKIEJAR$cookie_file_path,
        
    CURLOPT_COOKIEFILE$cookie_file_path,
        
    CURLOPT_COOKIE => 'symfony='.$_COOKIE['symfony'],
        
    CURLOPT_COOKIESESSION => true,
        
    CURLOPT_HTTPHEADER => array(
            
    'Content-Type: application/json',
            
    'Content-Length: ' strlen($body_json)
        )
    );
    curl_setopt_array(
        
    $curl_handle,
        
    $options
    );
    $response curl_exec($curl_handle);

    $error null;
    if (
    curl_errno($curl_handle)) {
        
    $error curl_error($curl_handle);
        echo 
    $error;
    }
    curl_close($curl_handle); 
    Könt ihr mir da bitte weiterhelfen?

    Danke!

  • #2
    Wie wäre es mit solchen absoluten Basics wie Code formatieren?
    Code:
    CURLOPT_RETURNTRANSFER => true,    CURLOPT_COOKIEJAR, $cookie_file_path);   CURLOPT_COOKIEFILE, $cookie_file_path);     CURLOPT_COOKIE => 'symfony='.$_COOKIE['symfony'],
    Da sind doch mehr schleießende Klammern drin, als davor überhaupt aufgemacht werden?!?!

    Kommentar


    • #3
      PHP-Code:
      'Content-Type: application/json'
      Du willst die Daten als json absenden, die API erwartet dann wohl auch json?
      Da wir die API nicht kennen, kann man nicht sagen wo der Fehler liegt.
      Was ist mit https?

      PHP-Code:
      CURLOPT_POSTFIELDS => $strBodyJson
      Wo wird $strBodyJson initialisiert?

      Kommentar


      • #4
        Zitat von erc Beitrag anzeigen
        Wie wäre es mit solchen absoluten Basics wie Code formatieren?
        Da sind doch mehr schleießende Klammern drin, als davor überhaupt aufgemacht werden?!?!
        Ja, sorry, ich wollte alle Kommentare entfernen und da habe ich versehentlich auskommentierten Code wieder in den Code aufgenommen.

        Zitat von protestix Beitrag anzeigen
        PHP-Code:
        'Content-Type: application/json'
        Du willst die Daten als json absenden, die API erwartet dann wohl auch json?
        Da wir die API nicht kennen, kann man nicht sagen wo der Fehler liegt.
        Was ist mit https?

        PHP-Code:
        CURLOPT_POSTFIELDS => $strBodyJson
        Wo wird $strBodyJson initialisiert?
        Genau, die API erwartet JSON. Letztendlich ist die API aktuell nur eine leere Symfony action:
        PHP-Code:
          public function executeIndex(sfWebRequest $web_request) {     return $this->renderText(json_encode(array('success' => true))); } 
        Https wird verwendet.
        $strBodyJson ist noch alt und wurde durch $body_json ersetzt.
        Ich kann sowohl die Login (mit auskommentiertem cURL-Aufruf), als auch die updateUser/index action problemlos nacheinander per PostMan aufrufen und erhalte success: true zurück.
        Da der Symfony-Login ein Cookie namens symfony erwartet, wenn der Benutzer eingeloggt ist, gehe ich davon aus, dass genau dieses fehlt, wenn ich den cURL-Aufruf absetze. Das Problem ist aber, dass ich gar nicht erst in die updateUser/index action komme, sondern Symfony das ganze schon vorab abfängt und eben die Meldung zurückgibt, dass der Benutzer nicht eingeloggt sei.

        Kommentar


        • #5
          [QUOTE=BLU;n1579587]Ja, sorry, ich wollte alle Kommentare entfernen und da habe ich versehentlich auskommentierten Code wieder in den Code aufgenommen.[/php]

          War nicht böse gemeint. Aber einmal überfleigen nach dem Absenden schadet nicht. Du hast ein Problem mit Cookies und der Part im Code, der die Cookies behandelt, ist ein Kopierfehler. Da ist mit helfen schwer.

          Vom Verständnis kann folgender Teil raus:
          PHP-Code:
              CURLOPT_COOKIEJAR$cookie_file_path,
              
          CURLOPT_COOKIEFILE$cookie_file_path,
              
          CURLOPT_COOKIESESSION => true
          Es bleibt:

          PHP-Code:
          CURLOPT_COOKIE => 'symfony='.$_COOKIE['symfony'], 
          und der Knackpunkt wird das $_COOKIE['symfony'] sein. Du schreibst du hast zwei unabhängig Anwendung. Wie kann Anwendung 2 die Cookies von Anwendung 1 kennen? Gar nicht!? Sowie ich das verstehe, musst du dich in Anwendung 2 einloggen und hast erst damit ein gütliges Cookies. Du musst also zwei Request ausführen. (dafür kannst du dann CURLOPT_COOKIEJAR/CURLOPT_COOKIEFILE verwenden.)

          Kommentar


          • #6
            Zitat von erc Beitrag anzeigen
            War nicht böse gemeint. Aber einmal überfleigen nach dem Absenden schadet nicht. Du hast ein Problem mit Cookies und der Part im Code, der die Cookies behandelt, ist ein Kopierfehler. Da ist mit helfen schwer.
            Ist so auch nicht rübergekommen und du hast natürlich recht. Vermutlich ist es mir nicht aufgefallen, weil ich pro Zeile eigentlich nur eine dieser CURLOPT_... Optionen stehen hatte.

            Zitat von erc Beitrag anzeigen
            Vom Verständnis kann folgender Teil raus:
            PHP-Code:
             CURLOPT_COOKIEJAR$cookie_file_path,
            CURLOPT_COOKIEFILE$cookie_file_path,
            CURLOPT_COOKIESESSION => true
            Das ist doch immerhin eine Erkenntnis. Ich bin mir selbst nicht sicher, welche dieser Optionen ich alle brauche. Da in den meisten Beispielen diese auch verwendet wurden, habe ich sie eben auch beibehalten.

            Zitat von erc Beitrag anzeigen
            Es bleibt:

            PHP-Code:
            CURLOPT_COOKIE => 'symfony='.$_COOKIE['symfony'], 
            und der Knackpunkt wird das $_COOKIE['symfony'] sein. Du schreibst du hast zwei unabhängig Anwendung. Wie kann Anwendung 2 die Cookies von Anwendung 1 kennen? Gar nicht!? Sowie ich das verstehe, musst du dich in Anwendung 2 einloggen und hast erst damit ein gütliges Cookies. Du musst also zwei Request ausführen. (dafür kannst du dann CURLOPT_COOKIEJAR/CURLOPT_COOKIEFILE verwenden.)
            Bei Symfony ist es so, dass ich mit sfGuard eine Instanz habe, die sich um die Benutzerrechte kümmert und die Benutzersession. Diese gilt für jede Applikation innerhalb meiner Anwendung. Also sowohl für die App1, als auch die App2.
            Wie gesagt, wenn ich per PostMan zuerst die URL updateUserDetails von App1 aufrufe, über die ich den Benutzer einlogge, die sieht dann etwa so aus:

            PHP-Code:
            publich function executeUpdateUserDetails(sfWebRequest $web_request)
            {
            // hole den token aus dem json request
            // validiere den token und wenn valide, dann decrypte den token und
            // hole den einzuloggenden User aus dem token.
            // hole das entsprechende User-Objekt aus der Datenbank:
            $user_object sfGuardUser::create()->findOneByUsername($username);

            $signedInUser $this->signIn($user_object);

            if (
            $signedInUser->isAuthenticated()) {
            // Starte den cURL-Aufruf in App 2 -> dieser ist für die Postman-Aufrufe auskommentiert
            return $this->renderText(json_encode(array('success' => true'msg' => 'Logged in')));
            }

            und danach dann updateUser/index in App 2, dann wird das Cookie auch mitgesendet und der Benutzer ist eingeloggt.

            Das komische ist nur, dass das Cookie für den erfolgreichen Login scheinbar nicht richtig mitgeschickt wird. Wenn ich mir $_COOKIE['symfony'] ausgeben lasse, dann wird mir auch ein Hash ausgegeben. Das Cookie wird also auch gesetzt.

            Kommentar


            • #7
              Ich habs geahnt. In den alten Versionen steck ich nicht drin. Du solltest aber allen potentiellen Problemen aus den Weg gehen können, wenn du statt $_COOKIE['symfony'] session_id() nimmst.

              Kommentar


              • #8
                Symfony 1 hat vor 8 Jahren sein "End of life" erreicht, das heißt auch seit 8 Jahren keine Security Fixes etc. mehr bekommen, ich bin mir nicht sicher ob eine Adaption der Anwendung in eine aktuelle Symfony Version nicht zielführender ist.
                In neueren Symfony Version hast du dann auch die Möglichkeit verschiedene Firewalls (Security Guards bei dir) zu einem User zu erstellen, wie z.B. ein klassischer Login und das Authentifizieren via API Token. So entfällt das rumbasteln mit CURL.

                Kommentar


                • #9
                  Zitat von erc Beitrag anzeigen
                  Ich habs geahnt. In den alten Versionen steck ich nicht drin. Du solltest aber allen potentiellen Problemen aus den Weg gehen können, wenn du statt $_COOKIE['symfony'] session_id() nimmst.
                  Dankeschön. Das werde ich ausprobieren.

                  Zitat von Zeichen32 Beitrag anzeigen
                  Symfony 1 hat vor 8 Jahren sein "End of life" erreicht, das heißt auch seit 8 Jahren keine Security Fixes etc. mehr bekommen, ich bin mir nicht sicher ob eine Adaption der Anwendung in eine aktuelle Symfony Version nicht zielführender ist.
                  In neueren Symfony Version hast du dann auch die Möglichkeit verschiedene Firewalls (Security Guards bei dir) zu einem User zu erstellen, wie z.B. ein klassischer Login und das Authentifizieren via API Token. So entfällt das rumbasteln mit CURL.
                  Ja, und das wird aktuell alles umgebaut, auch weg von Symfony/PHP. Allerdings werden bereits bestehende Funktionalitäten noch benötigt, weshalb ich diesen "Aufriss" nun machen muss. Die Applikation ist schon ziemlich komplex und groß, deshalb geht das nur Schritt für Schritt. Grundsätzlich hast du aber natürlich Recht und der Sprung von Symfony 1 auf eine neuere Version hätte vor langem erfolgen sollen.

                  Kommentar

                  Lädt...
                  X