Safari HTTP COOKIE
Notera att detta är ett mycket gammalt dokument (2010) och är inte aktuellt för nyare versioner av Safari
Detta är ett pågående dokument som kommer att ändras under tiden jag söker efter en lösning på problemet. Safari (Mac och Win) en lustig egenhet att man av oförklarliga anledningar blir utloggad. Jag har spårat problemet till vara ett specifikt Safari cookie problem/bugg, inte ett server problem.
Problemställning
Tanken med kakor är att de kan fungera som en unik användarnyckel som slängs/delas ut varje gång klienten gör en serverförfrågan. Så länge man är inloggad och jobbar (skickar server förfrågningar) så får man en ny nyckel till låset. Denna nyckel känner bara servern och klienten till. Om man tar paus, exempelvis en timme, så är nyckeln för gammal för att användas (Expire datumet har gått ut) och man måste logga in på nytt.
Huvudproblemet är att Safari plötsligt slänger kakor vars värden ändras frekvent.
På serversidan har jag gjort allt jag kunnat för att förhindra caching, hela vägen från Apache till CGI/PHP program, då detta är en applikation där data matas in. Data ska inte vara lagrat lokalt. Detta också för att försöka utröna om Safari struntar i att skicka lagrad kakinformation till servern. Jag har testat med "Safari WebKit r73316" men problemet kvarstår.
Testa själv: safari-cookie-test
Med detta exempel vill man förhindra lokal lagring av data (cache) men samtidigt måste webbklienten/webbläsaren lyda Expires värdet, inte hitta på något annat eller strunta i det som anges. Normalt sätt att bli av med kakan är att i http huvudet ange:
Set-Cookie: kaknamn=; Expires=Mon Nov 9 12:34:23 1970 GMT;
Alla webbläsare lyder detta och ser till att gamla kakor försvinner. Problemet med Safari är att den har en egen agenda vad beträffar Expires. Safari lagrar inte datumformat som GMT i kakfilen (på mac finns den i "~/Library/Cookies/Cookies.plist") men är helt säker på att det inte har med detta att göra då jag skrivit Expires=ett år fram i tiden.
Om man ska vara riktigt petig ska kakan se ut så här:
Set-Cookie: kaknamn=kakvärde; Domain=heap.se; Path=/; Expires=Mon Nov 19 12:34:23 2011 GMT; HttpOnly; Secure; Version=1;
(I dom allra flesta fall kommer man undan med betydligt enklare syntax och datum konvertering)
Sarafi cookie och problemsökning
Safari tål tydligen inte komma-tecken i kakor. Detta kan i och för sig lösas enkelt om man själv är den som utvecklar programvaror på servern. Det är svårare att göra något åt andra servrars problem. Så här ser request header informationen ut från Safari med en exempel-cookie:
$ENV{HTTP_COOKIE} .. Expires:Wed, 01 Dec 2010 09:38:42 GMT ..
Safari lägger själv till ett komma [,] efter Wed.. Från servern levererades kakan på detta sätt:
Set-Cookie: kaknamn=strang; path=/; expires=Wed Nov 30 09:38:43 2011 GMT
Det finns inget kommatecken i detta.
Kan det vara ett problem med cache control?
Ett till loggat exempel:
-- ### SAFARI KAKA 6) Pragma: no-cache ### ---
Har kaka: BD26CB22-FE62-11DF-A502-3D2A44C0B06F
Updaterat databasen med ny sträng:
F5FD8800-FE62-11DF-933A-452A44C0B06F
gammal
BD26CB22-FE62-11DF-A502-3D2A44C0B06F
Försöker skriva ny kaka:
Set-Cookie: heap=F5FD8800-FE62-11DF-933A-452A44C0B06F; path=/; expires=Fri Dec 2 22:24:43 2011 GMT
-- ### SAFARI KAKA 6) Pragma: no-cache ### ---
Har kaka: BD26CB22-FE62-11DF-A502-3D2A44C0B06F
INGEN SQL TRÄFF, kkaka:
BD26CB22-FE62-11DF-A502-3D2A44C0B06F
Safari tar inte emot uppdateringen av kakan trots att jag skriver den i HTTP huvudet. Den verkar vara cachad på något sätt.
Här har vi ett till exempel
Från server skickas denna identifierare:
7D957A0A-FE65-11DF-8125-012E44C0B06F
Så här ser det ut till Safari klienten:
Cache-Control:max-age=0, no-store
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:2956
Content-Type:text/html; charset=utf-8
Date:Thu, 02 Dec 2010 22:42:49 GMT
Expires:Fri, 03 Dec 2010 22:42:49 GMT
Keep-Alive:timeout=20, max=100
Pragma:no-cache
Server:Apache
Set-Cookie:heap=7D957A0A-FE65-11DF-8125-012E44C0B06F; path=/; expires=Fri Dec 2 22:42:49 2011 GMT
Vary:Accept-Encoding
Här stämmer kakorna överens. Vi väntar ett litet tag för uppdatera eller hämta en ny sida
Från server
-- ### SAFARI KAKA 6) Pragma: no-cache ### ---
Har kaka: 7D957A0A-FE65-11DF-8125-012E44C0B06F
Updaterat databasen med ny sträng:
2A68D7CC-FE66-11DF-8FC5-ED2E44C0B06F
gammal
7D957A0A-FE65-11DF-8125-012E44C0B06F
Försöker skriva ny kaka:
Set-Cookie: heap=2A68D7CC-FE66-11DF-8FC5-ED2E44C0B06F; path=/; expires=Fri Dec 2 22:47:39 2011 GMT
-- ### SAFARI KAKA 6) Pragma: no-cache ### ---
Notera! Den sista kakan tog den inte
(2A68D7CC-FE66-11DF-8FC5-ED2E44C0B06F <> 7D957A0A-FE65-11DF-8125-012E44C0B06F)
forts..
Har kaka: 7D957A0A-FE65-11DF-8125-012E44C0B06F
INGEN SQL TRÄFF, kkaka:
7D957A0A-FE65-11DF-8125-012E44C0B06F
Hos Safari klienten blir det då fel för att Safari har slängt bort nyckeln som gör att servern inte har någon identifikationssträng att gå efter.
Om jag skyndar mig att surfa så funkar det men så fort jag väntar lite blir jag utloggad.
Cache control
I CGI-script (Perl)
print "Pragma: no-cache\n";
print "Cache-control: no-cache\n";
PHP
header("Pragma: no-cache");
header("Cache-control: no-cache");
I Apache-conf (alternativt .htaccess)
(välj dock metod om apache eller PHP/Perl ska skriva ut headern)
# Cache policy
<Directory "/sökväg/till/publik/mapp/">
Header Set Pragma "no-cache"
Header Set Expires "Thu, 1 Jan 1970 00:00:00 GMT"
Header Set Cache-Control "max-age=0, no-store, no-cache, must-revalidate"
Header Unset ETag
FileETag None
</Directory>
I HTML-koden
<meta http-equiv="pragma" content="no-cache" />
Som parentes kan nämnas ett helknäppt IE förslag (som dock inget har att göra med Safari). Även detta har jag testat. Enligt Microsoft så är det inte säkert att detta förhindrar caching. Dom föreslår en, i mina-ögon, något märklig lösning genom att skriva två <head>:s i dokumentet. I första <head> skrivar man:
<META HTTP-EQUIV="REFRESH" CONTENT="5">
I den andra <head> (notera att det ska vara i samma HTML dokument)
<HTML>
<HEAD>
<META HTTP-EQUIV="REFRESH" CONTENT="5">
<TITLE>Dokument som inte ska lagrad i cache</TITLE></HEAD>
<BODY>
<!-- Den vanliga HTML koden här -->
</BODY>
<HEAD>
<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
</HEAD>
</HTML>
Länk:
http://support.microsoft.com/kb/222064
(Inget av detta avhjälper problemet i just Safari 5.1.1 och lägre)
Lösning/ nödlösning
Har ingen lösning på detta än. Det kan vara en bugg i Safari då detta problem inte finns i Google Chrome som också använder WebKit men av en senare version. Är det en bugg i Safari så är det inte så mycket att göra annat än att vänta en uppdatering där detta problem adresserats.
Nödlösningen är att inte uppdatera kakan alls utan sätta ett Exires-datum vid inloggning och låta det vara tills den förfaller efter en timme eller ett dygn. Detta minskar dock säkerheten i den applikationen som vill använda kakor som temporära nycklar. Det är inte heller användarvänligt då man kan föreställa sig en irriterad användare som plötsligt är utloggad när dom ska spara sin doktorsavhandling. I och med att inget är lagrat i cache så går det oftast inte att backa och hoppas att data ska finnas kvar. Snopet va! För att kringgå detta kan man strunta i att använda "Expires" när man sätter kakan. Kakan förfaller då när webbläsaren stängs av.
Relaterade dokument
HTTP Cookie
Dom vanligaste internet media typerna
HTTP Dateformat
[•]
"safari-cookieproblems", Hans E Andersson: 2010-12-03 12:42:32, ändrad: 2015-02-22 22:55:39