CGI::Session - Wie löscht man expired sessions??
Aqua
- perl
0 Tom0 Aqua0 Tom0 Aqua0 Tom0 Aqua0 Tom0 Aqua
0 Sven Rautenberg0 Peter Kaufmann
Hallo!
Wenn ich mit Session's arbeite verwende ich das Modul
CGI::Session, bzw. um genau zu sein das Modul
CGI::Session::MySQL.
Die Sessions werden in die Tabelle "sessions" geschrieben
und die Tabelle sessions wird mir von der offiziellen
Doku vorgeschrieben:
CREATE TABLE sessions (
id CHAR(32) NOT NULL UNIQUE,
a_session TEXT NOT NULL
);
Wenn ich nun ein Perl-Script habe welches eine Session
erzeugt, wird die ganze "Variablen-Wurst" in MySQL
eingetragen (in das Feld "a_session)
In meinem Test-Script habe ich die Expiration
auf 3 Sekunden gesetzt.
Wenn ich ein Session-Test-Script von mir aufrufe
mit einer abgelaufenen Session-ID dann bekomme ich
aus der session keine Daten mehr raus,
und die Session wird in der MySQL tabelle umbenannt
und die alten werte die gesetzt wurden werden gelöscht.
Somit bleibt es beim gleichen User immer eine gleiche
ID-Anzahl in der DB.
Ein User loggt sich auf der Seite ein und schließt irgendwann
einfach den Browser oder seine Internet-Verbindung
reißt ab oder .... jedenfalls loggt er nicht korrekt aus...
Also habe ich keine Möglichkeit mit delete die session zu killen,
und die Session wird mit "expire" beendet.
Dann bleibt diese Session in der Datenbank gespeichert!!
Und genau DAS ist das Problem!
Ich kann davon ausgehen dass 90% der User nicht auf
"logout" klicken werden sondern einfach den Browser
schließen werden.
Diese Sessions werden von CGI::Session nicht gelöscht,
und bleiben alle in der DB !
Ich habe gehofft dass die abgelaufenen Sessions
alle mal irgendwie gelöscht werden von MySQL
aber in meiner Datenbank sind nun schon 1400 abgelaufene
Session's und die werden anscheinend niemals gelöscht
wenn sie nur expire'n und nicht mit delete gelöscht werden.
Und delete bringt mir ja nichts weil es .. eben expire sein soll *g*
Das selbe Problem tritt auf wenn ich nicht das MySQL-Modul
von CGI::Session nehme sondern das normale CGI::Session
welches alles in Datafiles speichert.
Da passiert exakt das selbe.....
Frage:
Wie löse ich dieses Problem?
Eine Idee:
Es waere denkbar ein Perlscript zu schreiben
das man einmal am Tag laufen laesst und das alle
abgelaufenen Sessions auffindet und den entsprechenden
Session-Eintrag dann aus der DB löscht.
Das Problem ist aber dass keine Zeitangabe von expire
in einem extra feld steht,
sondern die gesagte query-wurst in einem einzigen
MySQL-Feld ist (a_session)
Somit kann ich nichtmal nach abgelaufenen Sessions suchen.
Und bei den Datafiles gehts ja auch nicht ....
Bitte sagt mir wie ich die nicht mehr aktives ID-Eintraege
in der MySQL Datenbank loswerden soll bzw.
die abgelaufenen Datafiles löschen soll.....
Es sollte auf jeden fall eine Sinnvolle lösung sein
und nicht im Stil von "sind 1000 eintrage da einfach 500 löschen)...
Das waere z.B. eine schlechte Lösung =)
Danke!
Aqua
Hello,
CREATE TABLE sessions (
id CHAR(32) NOT NULL UNIQUE,
lastclick timestamp,
a_session TEXT NOT NULL
);
Da kannst Du dann nur versuchen, die Tabelle entsprechend zu erweitern um die Spalte lastclick (oder wie auch immer Du die nennst) und dann von Zeit zu zeit alle zu alten Einträge rauslöschen. So ähnlich macht es ja der Garbage Collector in PHP auch.
Das Modul wird sich doch hoffentlich nicht sträuben, wenn die Tabelle mehr Spalten hat?
Das Schöne ist, dass die erste Spalte vom Typ Timestamp automatisch gepflegt wird von MySQL, sodass Dein Sesssionmodul gar nichts davon erfahren muss *grins* dass sie existiert
Liebe Grüße aus http://www.braunschweig.de
Tom
Hallo Tom!
Die Idee hatte ich auch schon!!!
Darf ich Dich schocken?
Was ist wenn das Modul irgendwo ein
insert into sessions values (?,?); hat ?
dann müssen die Felder exakt passen,
ein Feld mehr und du hast ein großes Problem...
Ich hab schon in den Source geguckt,
aber sooooo viel source wie die Module haben
trau ich mir nicht zu zu sagen,
ob ich nichts übersah was mit einem zusaetzlichen
Feld Probleme machen würde...
Danke,
Aqua
Hello,
Was ist wenn das Modul irgendwo ein
insert into sessions values (?,?); hat ?
dann müssen die Felder exakt passen,
Wieso sollte das stören? Die Values werden in der Reihenfolge zugewiesen, in der die Felder vorher benannt werden. Das geht bei SQL über NAMEN und nicht über POSITION. Das erste Timestampfeld in einer Tabelle wird von MySQL automatisch gepfelgt bei Datenmanipulation.
Du musst Dir da mMn gar keine Sorgen machen.
Liebe Grüße aus http://www.braunschweig.de
Tom
Hallo Tom
Sorry das ist Schwachsinn =)
Versuchs mal:
CREATE TABLE testing
(
id
varchar(32) NOT NULL default '',
a\_session
text NOT NULL,
foo
timestamp(14)
);
Nun mal ein korrekter insert wo man 3 Werte angiebt:
mysql> insert into testing values ('sadsad', 'safadsf', NOW());
Query OK, 1 row affected (0.02 sec)
Und hier das warum ich sage eine spalte zuviel gibt probleme:
mysql> insert into testing values ('sadsad', 'safadsf');
ERROR 1136: Column count doesn't match value count at row 1
Da ist eine spalte zu wenig...
Siehst Du meine bedenken?
LG
Aqua
Hello,
Hallo Tom
Sorry das ist Schwachsinn =)
Nein, Schwachsinn ganz bestimmt nicht! Bestenfalls wäre es eine Fehlüberlegung gewesen. Schwachsinnige pflegen nicht zu denken :-((
Nun mal ein korrekter insert wo man 3 Werte angiebt:
mysql> insert into testing values ('sadsad', 'safadsf', NOW());
Siehst Du meine bedenken?
Ich sehe, dass _das_ schwachsinnig ist. So schreibt man keine Module, die universell sein sollen. So kann man bestenfalls mal auf der Befehlszeile hantieren.
Nö, sehe ich nicht, denn korrekt ist auch:
mysql> insert into testing (id, a_session) values ('sadsad', 'safadsf');
mysql> select from testing where id = 'sadsad';
Und was steht drin in foo?
Ich habe in PHP eine eigene Sessionverwaltung für "Auth401" erstellt. Die besteht noch nicht einmal aus 100 Zeilen. Wieso sollte das in Perl soviel schwieriger sein?
Liebe Grüße aus http://www.braunschweig.de
Tom
Hallo Tom
Nö, sehe ich nicht, denn korrekt ist auch:
mysql> insert into testing (id, a_session) values ('sadsad', 'safadsf');
Klar das waere korrekt aber was ist wenn in dem
Modul das auf die andere korrekte art gemacht wurde?
Riskierst Du's?
Ich würde es mich nicht trauen ...
in irgendeinem ungetesteten Case kommt dann der Error ;(
LG
Aqua
Hello,
Riskierst Du's?
Ich würde es mich nicht trauen ...
in irgendeinem ungetesteten Case kommt dann der Error ;(
Wieviel Statements hat denn dieses ominöse Modul? Das wird man doch wohl checken können, ob da solche kurzsichtigen Statements drin stehen.
Liebe Grüße aus http://www.braunschweig.de
Tom
Hallo Tom
Also das CGI::Session::MySQL selbst ist nicht sooo groß
aber das normale CGI::Session ist sehr groß und
da werden noch andere CGI-Module eingebunden und im endeffekt
ist es sehr unübersichtlich....
Eine übersicht:
http://search.cpan.org/dist/CGI-Session/
Eine andere überlegung:
Wie schlecht sind Datafiles?
Die haben naemlich auch ein "letztes Bearbeituns-datum" (perldoc stat)
welches so wie der timestamp geht...
Dazu bitte das hier lesen:
[pref:t=66552&m=379904]
LG
Aqua
Moin!
mysql> insert into testing (id, a_session) values ('sadsad', 'safadsf');
Klar das waere korrekt aber was ist wenn in dem
Modul das auf die andere korrekte art gemacht wurde?
Niemand, der bei Sinnen ist und in der Lage, ein Perl-Modul zu schreiben, würde sich auf irgendeine geringste Weise auf undefinierte SQL-Statements verlassen.
Man macht es einfach NICHT, bei einem INSERT die zu belegenden Felder WEGZULASSEN. Macht man einfach nicht. Du kannst davon ausgehen, dass dies nicht geschieht.
Und ein wenig Quelltext nach "INSERT" zu durchforsten kann ja nicht wirklich ein Problem sein.
Riskierst Du's?
Ja. Definitiv. Weil ich nicht glaube, dass CPAN-Programmierer _so_ bescheuert sind.
Ich würde es mich nicht trauen ...
in irgendeinem ungetesteten Case kommt dann der Error ;(
Wenn du so wenig vertrauen in vorgefertigte Module hast - warum setzt du sie dann überhaupt ein? Kann doch genausogut sein, dass das Modul schlechte (vorhersagbare) Session-IDs erzeugt, und schon hast du ein Sicherheitsproblem beim Login-Bereich! Oder das Modul sichert aufgrund eines dummen Bugs Variablen mit dem Bestandteil "ID" falsch.
Man weiß es nicht. Man kann den Quellcode aber lesen, um sicherzugehen. Oder darauf vertrauen, dass das Modul sich wie gewünscht verhält, weil die Programmierer schlau genug waren, sich an gewisse Mindeststandards zu halten.
Die Angabe der zu belegenden Spalten bei INSERT gehört dazu.
- Sven Rautenberg
Hallo Aqua,
Klar das waere korrekt aber was ist wenn in dem
Modul das auf die andere korrekte art gemacht wurde?Riskierst Du's?
Ich würde es mich nicht trauen ...
lesen bildet ;-):
| You can also add any number of additional columns to the table, but the
| above "id" and "a_session" are required.
(CGI::Session::MySQL Dokumentation)
Der von Tom vorgeschlagene Weg dürfte also funktionieren. Einfacher dürfte es natürlich sein mit den vorgefertigten Funktionen des Moduls zu arbeiten: http://search.cpan.org/~sherzodr/CGI-Session-3.95/Session/Tutorial.pm#EXPIRATION
Grüße,
Peter