Halihallo Mark
Für mein Script nutze ich eine SessionID zur Verfolgung der Session (ohne Cookies, nur per GET). Gut und schön. Nun habe ich das Problem, das ich in meinem Script, in dem Fall um den es geht, eine Ein-Benutzer-Lizenz abbilden muss. Sprich, es soll immer nur ein Client auf die Applikation zugreifen können.
Nur um die Aufgabe richtig verstehen zu können:
Ein User hat Benutzer-Id und -Passwort und kann sich zu einer
bestimmten Zeit nur an einem Computer einloggen. Ist es hierbei
wichtig, dass der Benutzer nur von *genau* einem Client auf deinen
Service zugreifen kann? - Wenn ja: vergiss es, leider. Es geht nicht.
Ein Computer lässt sich nicht eindeutig identifizieren, zumindest
nicht über HTTP, TCP/IP.
Falls es nur darum geht, dass ein Benutzer während seiner Session
an einem Computer sitzen muss und den Service von keinem anderen
(über Kopieren der SessionId) Computer aus aufgerufen werden kann
(mit dem selben Login). Dann jain. Dies geht bedingt. Da HTTP selbst
Verbindungslos ist, kannst du niemals sicherstellen, dass der Request
von demselben Computer ausgelöst wurde. Wohl aber kannst du
sicherstellen, dass die Wahrscheinlichkeit klein ist, dass von zwei
Computern zur selben Zeit eine Anfrage kommen kann.
Intern habe ich eine Usertabelle in der DB, in welcher die SessionID des gerade aktiven Users abgespeichert ist - so kann ich u.a. kontrollieren, das immer nur ein Client aktiv ist. Theoretisch. Denn ein halbwegs gewiefter User bräuchte seinem Arbeitskollegen ja nur die SessionID mitteilen und dann könnten quasi 2, bzw. beliebig viele Clients, mit der gleichen Session aktiv sein.
Faktum: Du kannst den Client nicht sicher zu 100% identifizieren.
Faktum: HTTP ist Verbindungslos
Faktum: Clients/Parameter/Verbindungen können simuliert/emuliert
werden => Clientcomputer kann wechseln ohne dass dein Server
dies merkt.
Fazit: wie oben bereits beschrieben kannst du mit grosser
Wahrscheinlichkeit verhindern, dass zwei Computer mit demselben Login
zur selben Zeit aktiv sein können. Dies funktioniert wie folgt:
Wenn sich ein Benutzer einloggt, wird eine SessionId generiert. Diese
ändert jedoch bei jedem Zugriff. Wenn der Benutzer also die aktuelle
SessionId (oder in diesem Zusammenhang wohl treffender: RequestId)
dem "Nachbarn" weitergibt, könnte dieser zwar weiter den Dienst
benutzen, aber du würdest dich selber aus dem Dienst "ausschliessen",
da mit jeder RequestId lediglich ein Request angefordert werden kann.
Sobald ein Service (PHP-Seite) durch eine RequestId angefordert
wurde, wird diese RequestId deaktiviert und die nächste RequestId
generiert (und ggf. an alle Links und Formulare reingeschrieben).
Bei diesem Vorgehen gibt es jedoch grosse Probleme:
Man denke nur an die Situation, dass jemand auf die "Zurück"-Taste
des Browsers drückt und das Formular erneut absendet: Die im Formular
hardkodierte RequestId ist ja bereits deaktiviert und die Folge:
der User wird automatisch ausgeloggt...
Weiß jemand wie man das Problem umgehen kann? Gibts es Lösungsansätze? Ich müsste also irgendwie den Client eindeutig identifizieren können. Ich habe auch schon daran gedacht, in der Usertabelle zusätzlich die IP mit abzuspeichern, aber das dürfte wohl kaum zuverlässig funktionieren....
Richtig. Genausowenig zuverlässig ist meine obengenannte Lösung.
Es gibt meiner Meinung nach auch keine zuverlässige Lösung über
HTTP... Ggf. solltest du über ein Clientseitiges Programm nachdenken,
dass eine persistente Verbindung zum Server öffnet, damit wäre es
dann sogar relativ einfach umzusetzen...
Im Idealfall würde das dann so aussehen, das Benutzer 1 eingeloggt ist und die Applikation nutzt und Benutzer 2, welcher Clever ist und ohne Einloggvorgang einfach die SessionID von Benutzer 1 an die URL anhängt, abgelehnt wird..
Naja, "Ideal" wäre es, aber technisch Umsetzbar? - IMHO nein, nicht
100% ;-)
Viele Grüsse
Philipp