Forum: PC-Programmierung PHP Session Variable ändern.


von Rene K. (xdraconix)


Lesenswert?

Ich habe da gerade einen Knoten im Kopf.

Ich habe eine Seite (index.html) in denen per PHP eine Session gestartet 
wird. Über jquery lade ich eine php Seite jede Sekunde nach. In dieser 
wird die Session Variable zurück gelesen und genutzt. Das funktioniert 
alles tadellos.

Nun möchte ich aber via Button den Wert dieser Variable ändern.

Wie stelle ich das am dümmsten an? Kann ich per JS auf eine in PHP 
gesetzte Session Variable zugreifen?

von Frank D. (Firma: LAPD) (frank_s634)


Lesenswert?

Rene K. schrieb:
> Nun möchte ich aber via Button den Wert dieser Variable ändern.
https://www.w3schools.com/jsref/event_onclick.asp

von Bernd H. (geeky)


Lesenswert?

Rene K. schrieb:
> Kann ich per JS auf eine in PHP
> gesetzte Session Variable zugreifen?

Nein, von JS aus / client-seitig kann man üblicherweise nicht auf den 
Inhalt einer PHP-Session zugreifen.
Man könnte aber via JS einen Ajax-Request auf ein PHP-Script abfeuern, 
das dann wiederrum den Inhalt der PHP-Session wie gewünscht anpasst.
Alternativ: Das worum es geht gar nicht über die PHP-Session laufen 
lassen, sondern z.B. über ein eigenes Cookie.

von Rene K. (xdraconix)


Angehängte Dateien:

Lesenswert?

Bernd H. schrieb:
> Man könnte aber via JS einen Ajax-Request auf ein PHP-Script abfeuern,
> das dann wiederrum den Inhalt der PHP-Session wie gewünscht anpasst.

Super, danke dir. Das war der richtige Stichpunkt!

Via JS feuer ich einen ajax request auf ein separates PHP Script. Dieses 
setzt dann, entweder eine gewünschte Variable, oder aber toggelt eine 
Variable. (Im Bild "Hide / Show" um relevante Daten auszublenden z.b.)

JS:
1
$("button").click(function(event) {
2
  $.ajax({
3
    url : 'data/sessionbackend.php',
4
    type : 'post',
5
    data : {
6
      "var": "hideval",  //Oder andere Variable
7
      "val": "1",        //Wert, bei hideval aber irrelevant
8
    }
9
  })

PHP:
1
if(isset($_POST['var']) && isset($_POST['val'])){
2
    session_start();
3
    if($_POST['var'] == "hideval")
4
    {
5
        $_SESSION['hideval'] = !$_SESSION['hideval'];
6
    } else {
7
        $_SESSION[$_POST['var']]=$_POST['val'];
8
    }
9
} else {
10
11
}

Funktioniert tadellos!

von Roland P. (pram)


Lesenswert?

Rene K. schrieb:
> Funktioniert tadellos!

Du musst aufpassen, weil sich hier möglicherweise eine Sicherheitslücke 
anbahnt
1
$_SESSION[$_POST['var']]=$_POST['val'];

erlaubt es einen Angreifer jede beliebige Session-Variable zu 
manipulieren. Je nach Backend kann das keine, bis verheerende 
Auswirkungen haben.

LG Roland

von Rene K. (xdraconix)


Lesenswert?

Roland P. schrieb:
> erlaubt es einen Angreifer jede beliebige Session-Variable zu
> manipulieren. Je nach Backend kann das keine, bis verheerende
> Auswirkungen haben.

Ja stimmt, nicht nur das... er kann ja sogar selbst Session Variablen 
setzen... Okay, das muss ich mir tatsächlich nochmal überdenken. :-D

Dankeschön!

von Frank D. (Firma: LAPD) (frank_s634)


Lesenswert?

Rene K. schrieb:
> Funktioniert tadellos!
Aber irgendwie sinnfrei. Da kannste dir die Session auch gleich sparen.

von Rene K. (xdraconix)


Lesenswert?

Frank D. schrieb:
> Aber irgendwie sinnfrei. Da kannste dir die Session auch gleich sparen.

Jain, für das oben gezeigten Szenario stimmt das.

Da kommt aber noch einiges dazu. Das ist / war nur der erste Test um es 
möglichst einfach zu halten. Deswegen wollte ich halt einen Wrapper 
schreiben der Session Variablen mit var/val ändern kann.

Ich brauche halt eine Möglichkeit Global Variablen zu speichern auch 
über ein Close hinweg. Klar, kann man auch über eine DB machen, aber 
soviel Overhead finde ich dann doch zu doof.

von Frank D. (Firma: LAPD) (frank_s634)


Lesenswert?

Rene K. schrieb:
> Ich brauche halt eine Möglichkeit Global Variablen zu speichern auch
> über ein Close hinweg. Klar, kann man auch über eine DB machen, aber
> soviel Overhead finde ich dann doch zu doof.
Ich meinte eher sicherheitstechnisch, wenns eine interne/private 
Anwendung wird ist es egal.

Sessionsvars sind nicht für persistente Speicherung gedacht, auch wenn 
man das damit machen kann, früher oder später macht das immer wieder 
Ärger, vor allem wenn die Leute nicht wissen wie Sessions unter PHP und 
allgemein umgesetzt sind.

Wenn du keine DB willst, dann serialisiere dein Daten in eine Datei, das 
sind nur wenige Zeilen, da verschwindet dann auch nix irgenwann 
"überraschend" wie bei sessionvars und muss nicht umständlich beim 
einlesen parsen, das ist ein Einzeiler mit Serialisierung.

Je nach Anwendung kannst du auch im Browser dauerhaft Daten ablegen 
musst dann halt mehr mit JS rumhantieren ist aber manchmal einfacher als 
die Daten ständig hin und herzuschieben nur um sie aktuell zu halten wo 
sie evt. gar nicht gebraucht werden.

von Roland P. (pram)


Lesenswert?

Frank D. schrieb:
> Ich meinte eher sicherheitstechnisch, wenns eine interne/private
> Anwendung wird ist es egal.


Das stimmt nicht ganz. Man kann in eine öffentliche Webseite Code 
einbauen, der dann einen POST auf 
http://192.168.1.123/data/sessionbackend.php abschickt.
Stichwort: CORS/CSRF

Es ist aber hier viel Insiderwissen erforderlich und ich denke, dass 
deine Anwendung keib lohnendes Ziel wäre. Somit würde ich auch sagen, es 
ist fast egal.

Früher wurden aber über diese Technik oft Router angegriffen, bis die 
Hersteller dazugelernt haben.
Es reichte oft schon ein <img 
src='http://192.168.1.1/action?disconnect=true'; > in einer Website um 
Schabernack zu treiben

von Ein T. (ein_typ)


Lesenswert?

Rene K. schrieb:
> Ich brauche halt eine Möglichkeit Global Variablen zu speichern auch
> über ein Close hinweg. Klar, kann man auch über eine DB machen, aber
> soviel Overhead finde ich dann doch zu doof.

Es ist immer wieder erstaunlich, welche Klimmzüge manche Leute unter- 
und in Kauf nehmen, um drei Minuten Arbeit zu sparen. ;-)

von Rene K. (xdraconix)


Lesenswert?

Ein T. schrieb:
> Es ist immer wieder erstaunlich, welche Klimmzüge manche Leute unter-
> und in Kauf nehmen, um drei Minuten Arbeit zu sparen. ;-)

Nun, um in einem responsive Design Daten in eine Datenbank zu schreiben 
muss ich dann entweder NODE.js nutzen oder eben auch ein PHP basierendes 
Backend. Die "Klimmzüge" sowie die Sicherheit um die Daten an das 
jeweilige Backend zu "schicken" bleiben bei allen drei die gleiche.

Oder übersehe ich da etwas?

Klar, bei einer Datenbank bleiben die Daten auf jeden Fall permanent 
bestehen (Cookie löschen, Cookie abgelaufen... etc.). Die Klimmzüge aber 
sind durchaus "wuchtiger" als eine Session Variable zu ändern: Die Werte 
in die DB schreiben, die Werte beim Start auslesen...

von Ein T. (ein_typ)


Lesenswert?

Rene K. schrieb:
> Ein T. schrieb:
>> Es ist immer wieder erstaunlich, welche Klimmzüge manche Leute unter-
>> und in Kauf nehmen, um drei Minuten Arbeit zu sparen. ;-)
>
> Nun, um in einem responsive Design Daten in eine Datenbank zu schreiben
> muss ich dann entweder NODE.js nutzen oder eben auch ein PHP basierendes
> Backend. Die "Klimmzüge" sowie die Sicherheit um die Daten an das
> jeweilige Backend zu "schicken" bleiben bei allen drei die gleiche.

Puh, wo fange ich da an? Okay, machen wir mal was ganz Ungewöhnliches 
und
beginnen am Anfang.

Also, dieses HTTP ist ein Protokoll, das grundsätzlich erstmal keinen
Zustand hat. Eine Anfrage vom Webbrowser an den Webserver (Request) wird
mit vom Webserver beantwortet (Response), und an diesem Punkt ist das
Gespräch dann auch beendet. (Fisimatenten für mehr Performance wie HTTP
Keepalive sind hier erstmal uninteressant.) Wenn der Webbrowser nun eine
neue Anfrage an den Server und der eine Antwort an den Webbrowser 
schickt,
dann ist das ein neues Gespräch und vom vorherigen komplett unabhängig: 
der
Webserver kann nicht erkennen, ob diese zweite Anfrage von demselben
Webbrowser geschickt worden ist oder von einem anderen.

Nun ist es aber so, daß für bestimmte Anwendungsfälle zwingend nötig 
ist,
daß der Server den Webbrowser wieder erkennen kann, denk zum Beispiel an
einen Warenkorb. Deswegen kann der Webserver den Webbrowser anweisen,
kleine Datenmengen (die sogenannten Cookies) zu speichern und bei jedem
zukünftigen Request mit zu senden. Die Anweisung gibt der Webserver mit 
dem
HTTP-Header "Set-Cookie" und dabei können auch mehrere Cookies gesetzt
werden. Cookies können zudem einige Einstellungen enthalten, zum 
Beispiel
wann sie gelöscht werden, für welche Domain(s) sie gelten, und so 
weiter.

Das ist alles erstmal richtig schick und theoretisch könntest Du Deine
Daten auch einfach in Cookies speichern, die Dein Server mit 
"Set-Cookie"
an Deinen Webbrowser übergibt und die Dein Webbrowser dem Server im
nächsten Request wieder zurückschickt.

Wenn wir jetzt nochmal nachdenken, wird aber schnell klar, daß der 
Ansatz
zwei massive Probleme hat. Erstens dürfen Cookies höchstens 4096 Bytes 
groß
sein, da passen große Warenkörbe womöglich nicht hinein. Ein noch viel
größeres Problem ist allerdings, daß die Daten, die der Webbrowser an
Deinen Webserver im HTTP-Header "Cookie" schickt, manipuliert werden
können.

Solche Manipulationen lassen sich nur auf zwei Weisen verhindern: 
entweder
durch eine Verschlüsselung der Daten in den Cookies, was aber gemeinhin 
die
Größe der Nutzdaten weiter verringert. Oder, indem die Daten gar nicht 
an
den Webbrowser gesendet, sondern vom Webserver gespeichert werden und 
der
Webbrowser nur einen Cookie mit einer Kennung erhält, anhand derer der
Server ihn wiedererkennen und seine Daten wiederfinden kann.

Diese letztgenannte Technik wird als Session bezeichnet, und die Kennung
als Session-ID. Dabei ist es extrem wichtig, daß die Session-ID nicht 
von
Dritten erraten werden kann, sonst könnte ein Angreifer ja einfach eine
fremde Session übernehmen -- das nennt sich dann Session-Hijacking.
Dasselbe gilt. wenn jemand an eine fremde Session-ID kommt: dann er die
Session natürlich ebenfalls stehlen, deswegen HTTPS unser Freund.

Tatsache ist also nun, daß die Daten der Session auf dem Server 
verbleiben,
und der Browser Deines Besuchers nur die Session-ID kennt. Die kann er
ruhig manipulieren: wenn er eine falsche Session-ID schickt, findet der
Server eben einfach keine Session und keine Sessiondaten für diese
Session-ID.

Okay, schauen wir uns mal an, wie PHP das mit den Sessiondaten macht. 
Ohne
weitere Konfiguration speichert PHP die Sessiondaten in Dateien im
Verzeichnis  /tmp in Dateien, deren Name mit sess_ beginnt, danach folgt
die Session-ID. Das ist einerseits meistens nicht sehr performant (außer
bei Systemen, die /tmp in ein tmpfs im Arbeitsspeicher legen -- aber 
dort
sind die Sessiondaten bei jedem Reboot weg) und auch nicht besonders
sicher, denn Benutzer auf dem System können dann womöglich fremde
Session-ID mit einem einfachen ls(1) herausfinden.

Was heißt das jetzt alles für Dich, außer daß Dich so ein oller Pedant 
mit so Webgedöns zugelabert hat? Erstmal nur, daß Du mit dem JavaScript, 
das im Webbrowser läuft, nicht direkt auf Daten zugreifen kannst -- 
weder lesend noch schreibend -- die auf Deinem Webserver gespeichert 
sind. Dazu benötigst Du eine "aktive Komponente", also ein Programm 
(bzw. Skript) auf dem Server.

Andererseits ist die Frage, ob Deine Daten überhaupt dem Server bekannt
sein müssen oder es ausreicht, wenn Dein Webbrowser sie kennt. In diesem
Fall gäbe es nämlich viel elegantere Möglichkeiten im Browser, 
namentlich
LocalStorage, SessionStorage (hat trotz des Namens nichts mit den weiter
oben beschriebenen serverseitigen Sessions zu tun), und sogar eine
Datenbank (ok, ein NoSQL Key-Value-Store) namens IndexedDB.

Klar, auch für diese drei gilt: wenn die Inhalte daraus an den Server
gesendet werden, können sie manipuliert sein. Oder der Benutzer kommt
morgen mit einem anderen Gerät oder Browser, oder er löscht die Daten: 
dann
sind sie weg, also nicht verfügbar. So ganz sind die Notwendigkeiten und
Anwendungsfälle für die weiter oben beschriebenen serverseitigen 
Sessions
also noch nicht eliminiert.

Welche Methode Du wählst, oder ob Du womöglich sogar mehrere davon 
nutzt,
hängt also, wie so oft, sehr direkt von Deinem genauen Anwendungsfall 
ab.

> Klar, bei einer Datenbank bleiben die Daten auf jeden Fall permanent
> bestehen (Cookie löschen, Cookie abgelaufen... etc.). Die Klimmzüge aber
> sind durchaus "wuchtiger" als eine Session Variable zu ändern: Die Werte
> in die DB schreiben, die Werte beim Start auslesen...

Ja, und dazu kommt der Aufwand, die Datenbank aufzusetzen, zu betreiben, 
und zu pflegen... wobei "Datenbank" ja nicht unbedingt ein klassisches 
SQL-RDBMS sein muß, sondern auch etwa ein simpler Key-Value-Store sein 
kann. Es kommt, wie so oft, eben immer auf die genauen Anforderungen an.

von Rene K. (xdraconix)


Angehängte Dateien:

Lesenswert?

Ein T. schrieb:
> Puh, wo fange ich da an? Okay, machen wir mal was ganz Ungewöhnliches
> und
> beginnen am Anfang.

Vielen lieben Dank für deine ausführliche Erklärung in Sachen Cookies 
und Sessions... Hat so einiges Licht ins Dunkel gebracht! :-D

Ich bin da nun auch völlig weg von Sessions und Cookies gekommen. 
Aktuell würde ich sie tatsächlich nur dazu nutzen um den Blur zu setzen 
oder nicht. Das habe ich nun ausschließlich mit JS umgesetzt und einfach 
CSS Wert über JS geändert. Im Grunde muss das nicht "gespeichert" sein. 
Alles andere kommt dann nach und nach über ein User Login, da geht das 
eh in eine Datenbank.

von Ein T. (ein_typ)


Lesenswert?

Rene K. schrieb:
> Ein T. schrieb:
>> Puh, wo fange ich da an? Okay, machen wir mal was ganz Ungewöhnliches
>> und beginnen am Anfang.
>
> Vielen lieben Dank für deine ausführliche Erklärung in Sachen Cookies
> und Sessions... Hat so einiges Licht ins Dunkel gebracht! :-D

Cool, das freut mich sehr -- zumal ich schon befürchtet hatte, daß Du 
das alles schon gewußt und nur müde abgewunken hättest. :-)

> Ich bin da nun auch völlig weg von Sessions und Cookies gekommen.
> Aktuell würde ich sie tatsächlich nur dazu nutzen um den Blur zu setzen
> oder nicht. Das habe ich nun ausschließlich mit JS umgesetzt und einfach
> CSS Wert über JS geändert. Im Grunde muss das nicht "gespeichert" sein.
> Alles andere kommt dann nach und nach über ein User Login, da geht das
> eh in eine Datenbank.

Ach, ich habe jetzt sicher 15 Jahre lang sehr wenig mit JavaScript 
gemacht, höchstens mal fertige Libraries für Pandas wie Bokeh und Plotly 
benutzt. In letzter Zeit spiele ich allerdings ein wenig mit WebSockets 
und Server-Sent Events mit Go(lang), Svelte und HTMX... und stelle fest, 
daß das JavaScript zwar immer noch nicht schön, aber doch angenehmer 
geworden ist. ;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.