Gå til innhold

Tilgangskontroll til undermapper i www


Anbefalte innlegg

Hei

Jobber med et bildegalleri hvor jeg ønsker at bildene ikke skal være tilgjengelige for hvermannsen. Slik saken er nå kan personer som ikke har logget inn "gjette" (eller få tilsendt) url'en til bildene for å se på de. Dette er ikke ønskelig og har prøvd flere måter å styre tilgangskontrollen på uten hell så langt.

 

Prøvde først å bruke .htaccess som jeg igjen skulle koble til en database for å hente ut brukere osv. Problemet jeg møtte på her var at jeg simpelten ikke fikk til å bruke mysql_auth_module med apache. Apache starta aldri opp når jeg loada modulen.

 

Så det jeg har gjort nå er å stenge av alle bildemappene med "Deny from all" i en .htaccess-fil. Prøver så å få henta frem bildene med header()-funksjoner. Har fått til å hente en fil til nedlasting på denne måten ved å følge et eksempel som ser slik ut:

<?php
session_start();
if($_SESSION["logged"]!=1) die("error");
function get_file($filename)
{
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.$filename);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($filename));
ob_clean();
flush();
readfile($filename);
exit;
}
if(isset($_GET["file"]))
{
//some simple security.
$filename=stripslashes($_GET["file"]);

if ($handle = opendir('/direcotry/with/files')) {
while (false !== ($file = readdir($handle))) {
	if ($file == $filename && $file!="." && $file!="..") {
			get_file($filename);
	}
}
}
}else die("no file was sent");
?>

 

Hvordan kan jeg bruke header()-funksjonen til å få vist bildene som ligger i mappene?

 

Hvis noen har andre løsninger på problemet mitt er jeg veldig åpen for forslag.

 

- Mikael

Lenke til kommentar
Videoannonse
Annonse

Header-funksjonen sender bare metadata, altså informasjon om hva du sender. Du kan ikke bruke headers til å gi brukere adgang til noe. Skjønner jeg deg rett, så vil du vite hvordan du kan få listet alle filene i bildemappen din så brukerne kan se de? Kan ta et eksempel på hvordan man kan implementere et bildegalleri med bilder i en privat mappe:

 

Først definerer vi hvilke filtyper vi ønsker å kunne sende til brukeren, og hvilken mappe de ligger i.

 

common.php

<?php
/* Bildene ligger i mappen 'private'. */
$img_loc = 'private';
/* Dette er filtypene du vil vise */
$mime_types = Array(
'jpg',
'jpeg',
'gif',
'png'
);
?>

 

Så setter vi opp en side der brukerne kan gå inn og se bildene.

 

index.php

<?php
require('common.php');
/* Få liste over alle bildene i private */
$img_list = glob(
sprintf('%s/*.{%s}', $img_loc, join(',', $mime_types)),
GLOB_BRACE
);
/* Print ut lenker til alle bildene */
print '<ul>';
foreach($img_list as $img_uri) {

/* Hent ut selve filnavnet */
$tmp = explode('/', $img_uri);
$img_name = end($tmp);

printf('<a href="%s"><img src="get.php?file=%s" width="200" /></a><br />', $img_uri, $img_name);
}
print '</ul>';

?>

 

PHP lister her alle filene i mappen og lager img-elementer for hvert bilde. Her kan du se at img-elementene peker til get.php, og bruker filnavnet som parameter.

 

get.php

<?php
require('common.php');
try {
// Sjekk login først
if(!$_SESSION['login'])
 throw new Exception('User is not signed in');

if(!array_key_exists('file', $_GET))
 throw new Exception('No file input');

/* Sjekk at filnavnet ikke inneholder noe skummelt */
preg_match('/[a-zA-Z0-9\.\s\-]*$/', $_GET['file'], $match);

if(count($match) != 1)
 throw new Exception('Invalid file name');

/* Sett opp full URI */
$uri = sprintf('%s/%s', $img_loc, $match[0]);

/* Finn ut hvilken filtype vi skal sende */
$tmp = explode('.', $uri);
$mime = end($tmp);

/* Sjekk at filtypen er på listen vår over godkjente filtyper */
if(!in_array($mime, $mime_types))
 throw new Exception('Invalid mime type');

/* Sjekk at filen finnes */
if(!file_exists($uri))
 throw new Exception('File not found');
/* Åpne filen for lesing */
$fp = fopen($uri, 'rb');

if(!is_resource($fp))
 throw new Exception('File opening error');
/* Send litt headers */
header(sprintf("Content-Type: image/%s", $mime));
header("Content-Length: " . filesize($uri));
/* Send bildet */
fpassthru($fp);

}
catch(Exception $e) {
// gi ut feilmelding
// eventuelt kan man sende ut et standard "noe gikk feil"-bilde
echo $e->getMessage();
}
?>

 

Til sist har vi altså get.php som sørger for å sende filene.

 

Beklager at alle innrykkene forsvant, diskusjon.no liker meg visst ikke lenger. Dette virker i hvertfall slik at brukeren går inn på nettsiden din, PHP lister alle bildene i mappen ('private') og lenker til disse med img-elementene gjennom get.php. Get.php får så en forespørsel for hver fil i mappen. F. eks. get.php?file=winter.png. Get.php sjekker at brukeren er logget inn, alt filen finnes, at filtypen er riktig osv. og sender til slutt bildet.

 

Vel, det er i hvertfall et eksempel på hvordan man kan gjøre det. Du vil antageligvis ikke liste alle bildene på en gang og gjøre en del andre endringer, men fremgangsmåten er den samme uansett.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...