Borewa: Cookie auslesen

Guten Tag,
ich möchte Cookies setzen und wieder auslesen für ein Login.
Das klappt auch fast.

$q = CGI->new;  
  
#[... Logindaten prüfen ...]  
  
$cookie1 = $q->cookie(  
-name => "ma_id",  
-value => $user{mitarbeiter_id},  
-expires => "+3d",  
-path => "/",  
);  
		  
$cookie2 = $q->cookie(  
-name => "session_id",  
-value => "$session_id",  
-expires => "+3d",  
-path => "/",  
);  
		  
  
print "Set-Cookie: $cookie1\n";  
print "Set-Cookie: $cookie2\n";  
print $q->header();

Danach versuche ich direkt das Cookie wieder zunutzen, in diesem Fall kurz einfach

print $q->cookie("ma_id") ."<-->". $q->cookie("session_id");code]  
  
Nun wird nur "<-->" ausgegeben, d.h. er konnte die Cookies nicht auslesen.  
  
Wenn ich aber nun die Seite neulade oder eben einen andern Link nutze, der dann wieder auf die gleiche weise die Cookies ausliest (ohne wie oben neue zu schreiben) zeigt er direkt die richtigen werte an.  
  
Ich verstehe nicht wieso ich erst nach einem reload auf die Werte zu greifen kann und nicht direkt nach print $q->header();  
  
Irgendwie muss meine Lösung ja halb richtig sein, weil ich zumin nach dem Reload auf die Werte bzw. die Cookies zugreifen kann. Sonst hätte ich vermutet das es etwas mit  
  
[code lang=perl]print "Set-Cookie: $cookie1\n";  
print "Set-Cookie: $cookie2\n";  
print $q->header();

zutun hat.

Ich habe zwar schon öfters gesehen das man
print $q->header(-cookie=>[$cookie1,$cookie2]);
macht und habe dies auch probiert, aber leider mit gleicher Wirkung.

  1. Ich habe zwar schon öfters gesehen das man
    print $q->header(-cookie=>[$cookie1,$cookie2]);
    macht und habe dies auch probiert, aber leider mit gleicher Wirkung.

    So funktioniert es, wenn es bei dir nicht funktioniert, machst du was falsch. Du bist auch 100% sicher, dass davor nichts anderes ausgegeben wurde?

    Struppi.

  2. Kaum macht man es richtig, schon geht es! ;)

      
    use CGI qw();  
    my $cgi = CGI->new;  
      
    my %user = (mitarbeiter_id => 123);  
    my $session_id = 456789;  
      
    my @cookies = (  
        $cgi->cookie(  
            -name    => 'ma_id',  
            -value   => $user{mitarbeiter_id},  
            -expires => '+3d',  
            -path    => '/',  
        ),  
        $cgi->cookie(  
            -name    => 'session_id',  
            -value   => $session_id,  
            -expires => '+3d',  
            -path    => '/',  
        ));  
      
    print $cgi->header(-type => 'text/plain;charset=UTF-8', -cookie => [@cookies]);  
      
    print "Im HTTP-Response wurden folgende Cookies geschickt:\n";  
    print map { sprintf "%s<-->%s\n", $_->name, $_->value } @cookies;  
    
    

    Erklärung: weil das Modul CGI.pm keine klare Trennung von HTTP-Request und -Response vornimmt (wie z.B. bei libwww-perl), sondern alles in eine Objektinstanz stopft, hast du falsch geschlussfolgert, dass man gerade soeben gesetzte Cookies auch wieder mit der Methode cookie auslesen kann. Tatsächlich bezieht sich das Setzen auf HTTP-Response, das Auslesen auf HTTP-Request (wo sie logischerweise noch nicht vorhanden sein konnten). Die Vorgehensweise ist einfach, sich die Cookieobjekte zu merken. Sie sind von der Klasse CGI::Cookie.

    1. mhhm ... danke, das muss man ja erstmal wissen.

      Gibt es nun aber eine Möglichkeit zu erkennen ob ein Cookie per HTTP-Request oder -Response verfügbar ist?

      sub get_cookie($) {  
      	&debug("Die Funktion 'get_cookie' wurde aufgerufen");  
      	  
      	$cookie_name = shift;  
        
      	if($cookies{$cookie_name} ne "") {  
      		return $cookies{$cookie_name}->value;  
      	}  
      	else{  
      		return cookie($cookie_name);  
      	}  
      		  
      	&debug("Die Funktion 'get_cookie' wurde erfolgreich beendet");	  
      }
      

      Habe sonst einfach diese Funktion geschrieben und meine Cookies statt in $cookie1 und $cookie2 in einem Hash mit $cookies{ma_id} und $cookies{session_id} gespeichert.

      So bin ich ja recht flexibel, falls ich noch weitere Cookies anlegen möchte.

      1. hi,

        Gibt es nun aber eine Möglichkeit zu erkennen ob ein Cookie per HTTP-Request oder -Response verfügbar ist?

        Schaun wir mal ins Protocol (HTTP). Cookies werden im Header übertragen. Beim Request sendet der UserAgent den Cookie im Header, der Value findet sich dann serverseitig in der Umgebung in  $ENV{HTTP_COOKIE}

        name=wert; name2=wert2

        ganz genauso sieht die Zeile auch im Request Header aus

        COOKIE: name=wert; name2=wert2

        auch wenn da stehen würde

        Cookie: name=wert

        serverseitig wird für %ENV alles in UC umgesetzt und HTTP_ vornedran gehängt.

        In der Response steht der Cookie auch im Header:
        Set-Cookie: name=wert [;flags]

        und bekanntlich speichert ein UA den auf der Festplatte.

        Hotti