Undgå at folk linker til billeder
Hvis man vil undgå at folk linker til ens billeder eller videoer, kan man med mod_rewrite kigge på Referer-headeren, og se om brugeren kommer fra ens eget domæne
Her viser jeg hvordan man nægter adgang til .png-filer hvis folk ikke kommer fra www.example.com
1 2 3 | RewriteEngine On RewriteCond %{HTTP_REFERER} !^http://www.example.com/ RewriteRule \.png$ – [F] |
[F] betyder Forbidden.
Det hjælper selvfølgelig ikke mod de folk der selv kan finde ud af at sætte Referer-headeren, men det hjælper mod almindelige browsere.
Sprogstyring via mod_rewrite
En lille idé til hvordan man kan styre sprog via Apaches mod_rewrite.
Normalt definerer jeg en konstant ved navn URL der indeholder den absolutte adresse til forsiden af mit website. Fx:
1 | define("URL", "http://www.example.com"); |
Hver gang jeg skal linke i HTML/Smarty eller sende videre via PHP bruger jeg konstanten.
Nu vil jeg tilføje sprog som et ekstra “lag” på mine adresser, så jeg fremover kalder example.com/en/about.php for den engelske udgave, og example.com/fr/about.php for den fanske udgave af about.php; men jeg vil ikke have to versioner af about.php liggende.
Derfor laver jeg en lille rewrite-regl der omskriver førnævnte adresser til example.com/about.php?lang=en og example.com/about.php?lang=fr.
Reglen kan ses herunder. Bemærk at jeg kun checker på to a-z og ikke på de tilladte sprog. Det burde man måske gøre.
1 2 | RewriteEngine On RewriteRule ^([a-z]{2})/(.*)$ $2?lang=$1 [QSA] |
Jeg tilføjer QSA som betyder query string append, hvilket gør at eventuelle andre parametre til siden stadig kommer med.
Næste trin bliver at lave noget PHP der behandler ovenstående. Jeg vil typisk sætte min URL-konstant på i en header-fil der bliver inkluderet på alle sider. Før jeg definerer min konstant, laver jeg et check på $_GET['lang'] for at se om den er på listen over tilladte sprog. Er den det liver den tilføjet til konstanten, og på den måde vil alle mine linke indeholde sprogangivelsen.
1 2 3 4 5 6 7 8 9 | $valid_languages = array("en", "de", "fr", "da"); if (in_array($_GET['lang'], $valid_languages)) { define("URL", "http://www.example.com/".$_GET['lang']); } else { define("URL", "http://www.example.com"); } |
Det kan måske være meget smart at have to konstanter til URL’en. Én med sprog, og en uden, da det ikke er alle steder man vil angive sprog – fx billeder, stylesheets og javascript m.m.
Få styr på ens domæne
De fleste har både example.com og www.example.com, og de to domæner viser samme site, men det giver tit nogle problemer.
For mit vedkommende har jeg typisk en konstant der hedder URL der indeholder “http://www.example.com”, og så bruger jeg den hver gang jeg linker til undersider. Går man ind på example.com og logger direkte ind fra forsiden, vil man blive sendt til www.example.com der sætter en cookie og sender en tilbage til siden man kom fra. Problemet er bare at www.example.com ikke altid sætter cookies for *.example.com. Hvilket resulterer i at man ikke bliver logget ind.
Der kan være andre problemer. Måske har man *.example.com og nogen ved et uheld kommer til at linke til ww.example.com, og Google indekserer den side. Så har man lige pludselig tre kopier af sit site liggende i Google.
Løsningen er følgende i ens .htaccess:
1 2 3 | RewriteEngine On RewriteCond %{HTTP_HOST} !^www\.example\.com$ RewriteRule ^(.*) http://www.example.com/$1 [L,R=301] |
Jeg kontrollerer domænenavnet om det er www.example.com. Hvis ikke, så sender jeg videre til www.example.com. Jeg ta’r selvfølgelig hele URL’en med i videresendingen.
“If-sætninger” i Apaches mod_rewrite
Når jeg udvikler gør jeg det typisk på min egen maskine, og så via SVN synkroniserer jeg med live-serveren. Det gi’r tit nogle problemer med rewrite-regler, da de typisk vil være anderledes fra localhost til den endelige server.
Min løsning på det er Skip-flaget der fortæller Apache hvor mange regler den skal springe over.
Nedenstående eksempel springer én regel over hvis man sidder på localhost.
1 2 3 4 5 6 7 8 9 10 11 12 | RewriteEngine on RewriteCond %{HTTP_HOST} ^localhost$ RewriteRule .* - [S=1] # Bliver ikke kørt på localhost RewriteCond %{HTTP_HOST} !^www\.example\.com$ RewriteRule ^(.*) http://www.example.com/$1 [L,R=301] # Bliver kørt på alle sites RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^[^/]+-([0-9]+)$ item/view/$1 [QSA] |
Se mere i manualen for mod_rewrite.
Underdomæner på en smart måde
En nem måde at lave underdomæner på er ved at have wildcard-DNS. Dette opnår man typisk ved at lave et CNAME hvor *.foo.dk peget på hoveddomænet foo.dk.
Når folk ser foo.dk eller www.foo.dk leverer serveren typisk index.php; men forestil jer, at man vil have serveren til at vise domain.php med ‘bar‘ som argument, hvis brugeren fx kalder bar.foo.dk.
Det kan forholdsvist nemt løses vha. følgende i ens .htaccess.
1 2 3 4 | RewriteEngine On RewriteCond %{HTTP_HOST} !^(www\.)?foo\.dk$ RewriteRule .* %{HTTP_HOST} [C] RewriteRule ^([^.]+) domain.php?host=$1 [L] |
Jeg omskriver kun hvis HTTP_HOST ikke er foo.dk eller www.foo.dk, og jeg omskriver http://bar.foo.dk/ til http://bar.foo.dk/bar.foo.dk for derefter at pille underdomænet ud, og vise domain.php?host=bar.
Bemærk at omskrivningen sker internt, så adresselinien ændrer sig ikke.
Det burde derefter være trivielt at lave nogle checks i domain.php på $_GET['host'].
Tricket i ovenstående ligger i at kæde de to rewrite-regler sammen vha. [C] der står for chain.

Jeg hedder Morten, og jeg har udviklet webapplikationer siden slutningen af 90'erne.