|
|
Ofte hører/læser jeg om folk der har problemer med at få logget brugere af deres site når brugerens session udløber.
Jeg har for nylig fedtet med en koncept som benytter global.asa til denne og andre ofte session-relaterede opgaver.
Jeg har desuden kogt på et koncept, som gemmer brugerens state i en tekstfil på harddisken og sørger for at indlæse brugerens state igen, næste gang brugeren laver en forspørgsel til serveren (og dermed opretter en session). Det eneste man har brug for er i realiteten en eller anden måde at identiificere brugeren på og så at brugerens browser understøtter/tillader cookies...
Med det koncept kan brugeren i realiteten være offline uden en aktiv session lige så længe dennes cookie er bevaret på den maskine der browses fra. Der er naturligvis nogle sikkerhedsmæssige aspekter man skal tage hensyn til, for hvis brugeren glemmer at logge af (og dermed slette den cookie der giver adgang til autologin), så har en evt. anden bruger af den maskine adgang til den første brugers oplysninger. Derfor er det en god idé kun at tillade autologin på en maskine som kun benyttes af samme bruger.
Nedenfor har jeg vist et eksempel på en global.asa, som benytter en offline session-state på serverens harddisk, med en cookie som det eneste på klienten, til at holde på brugerens sessiontilstand. Eksemplet illustrerer i øvrigt også hvordan man kan lægge sine indstillinger for websitet i en ekstern fil (f.eks. connectionstrenge til databasen m.m.).
<!-- METADATA TYPE="typelib" uuid="00000205-0000-0010-8000-00AA006D2EA4" -->
<SCRIPT language=vbscript runat="server">
' ================================================================================
' ================================================================================
Sub Application_OnStart()
dim fso, f, alltext, eqp, key, value, ln, aLines
on error resume next
set fso = Server.CreateObject("Scripting.FileSystemObject")
set f = fso.OpenTextFile("C:\inetpub\settings.txt", 1, true)
alltext = f.ReadAll()
f.close
set f = nothing
set fso = nothing
aLines = Split(alltext, vbCrLf)
for each ln in aLines
eqp = instr(ln, "=")
if eqp > 0 then
key = left(ln, eqp - 1)
value = mid(ln, eqp + 1)
Application.Contents(key) = value
end if
next
err.Clear
on error goto 0
End Sub
' ================================================================================
' ================================================================================
Sub Session_OnStart()
dim fso, f, eqp, key, value, alltext, ln, userfilename, aLines, brugerid
dim statefolder
dim conn, sql
on error resume next
' statefolder indeholder stien til den mappe
' som indeholder alle brugeres tilstande...
statefolder = Application("statefolder") & ""
set fso = Server.CreateObject("Scripting.FileSystemObject")
brugerid = Request.Cookies("brugerid") & ""
if brugerid <> "" then
userfilename = statefolder & brugerid & ".txt"
if fso.FileExists(userfilename) then
set f = fso.OpenTextFile(userfilename, 1, true)
alltext = f.ReadAll()
f.close
set f = nothing
' Aflæs alle liniernes nøgle og tilhørende værdi
' og læg dem i session-objektet
aLines = Split(alltext, vbCrLf)
for each ln in aLines
eqp = instr(ln, "=")
if eqp > 0 then
key = left(ln, eqp - 1)
value = mid(ln, eqp + 1)
session(key) = value
end if
next
' Ryd op, så der ikke ligger en masse ubrugelige session-filer
' og flyder som risikerer at blive brugt ved en senere lejlighed
call fso.DeleteFile(userfilename)
' log brugeren på systemet igen (styres i dette eksempel via databasen)...
set conn = Server.CreateObject("ADODB.Connection")
conn.open Application("connection")
sql = "UPDATE bruger " & _
"SET online = 1" & _
"WHERE brugerid = " & brugerid
conn.execute(sql)
conn.close
set conn = nothing
end if
end if
set fso = nothing
err.clear
on error goto 0
End Sub
' ================================================================================
' ================================================================================
Sub Session_OnEnd()
dim fso, f, key
dim statefolder
dim medlemsnr
dim conn
on error resume next
statefolder = Application("statefolder") & ""
if session("brugerid") & "" <> "" then
brugerid = session("brugerid") & ""
set fso = Server.CreateObject("Scripting.FileSystemObject")
set f = fso.OpenTextFile(statefolder & brugerid & ".txt", 2, true)
f.WriteLine "LAST_SESSION_TIMEOUT=" & now
for each key in Session.Contents
if key <> "LAST_SESSION_TIMEOUT" then
' Da LAST_SESSION_TIMEOUT er en variabel som systemet indsætter når
' en session udløber, så skal den ikke gemmes fra session-objektet
' når session-oplysningerne serialiseres... alt andet skal med.
call f.WriteLine(key & "=" & Session.Contents(key))
end if
next
f.close
set f = nothing
set fso = nothing
' Sæt brugerens status til offline i databasen
sql = "UPDATE bruger " & _
"SET online = 0 " & _
"WHERE brugerid = " & brugerid
set conn = Server.CreateObject("ADODB.Connection")
conn.Open Application("connection")
conn.Execute(sql)
conn.Close
set conn = nothing
err.clear
end if
on error goto 0
End Sub
</SCRIPT>
Ovenstående eksempel kræver, at der ligger to nøgler i settings.txt, nemlig connection og statefolder. Connection indeholder forbindelsesoplysninger til databasen og statefolder indeholder en absolut stiangivelse til den mappe hvor tilstandsfilerne skal gemmes. Det kunne se således ud:
connection=Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\inetpub\data\sitedb.mdb;
statefolder=c:\inetpub\state\
|