Avatar billede larma Nybegynder
29. marts 2007 - 17:33 Der er 20 kommentarer og
2 løsninger

Sikre mappeinnhold

Hei.

Jeg har lavet en webside hvor det er mulig å laste ned dokumenter fra forskjellige mapper. Jeg har da en hovedmappe som også består av flere undermapper, hvor det da er gemt forskjellige dokumenter. Og mitt ønske er å kunne sikre mappeinnholdet mot forsøk på å hente det via den direkte stien/url'en. Jeg har kikket litt på .htaccess, men har ikke funnet en tilfredstillende løsning. Mye pga at det er en side hvor brukere kan registrere seg, og jeg må da evt oppdatere en .htpasswd fil hele tiden. Og jeg lurer da på om det er noen som har et bud på et godt alternativ, eller en god .htaccess løsning? Ønsket er at det lige ligger en sjekk-filen i rod-mappen til mappesystemet.
Avatar billede amews_aj Nybegynder
29. marts 2007 - 17:49 #1
Du kan vist lave en htaccess som blokerer mappen helt:
Order allow,deny
Allow by none
Deny from all


Så kan du bruge php til at tvinge browseren til at downloade stien. Du skal bare gøre så den kun gennemtvinger download hvis personen der er logget ind har ret til det. Jeg tror det vil virke sådan.
Her er php:
<?php
$filnavn = "fil_at.hente";

$fil = $_SERVER['DOCUMENT_ROOT'] . "/mappe_til_filer/" . $filnavn;
if (file_exists($fil) && $filnavn != "" ) {
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Content-Type: application/octet-stream");
    header("Content-Length: " . filesize($fil));
    header("Content-Disposition: attachment; filename=".$filnavn."");
    readfile($fil);
}else{
    echo "Filen findes ikke!";
}
?>


Husk så, at da den sender headers, må du ikke udskrive noget andet HTML på siden inden denne php kode er kørt.
Avatar billede amews_aj Nybegynder
29. marts 2007 - 17:49 #2
Det var:
Order allow,deny
Allow from none
Deny from all
Avatar billede coderdk Praktikant
29. marts 2007 - 17:59 #3
Hvis vi antager at din mappe er:

/docs/

Og du har mapper under:

/docs/manualer/
/docs/insiderviden/

Så lav en .htaccess i /docs/ med flg. indhold:

Order allow,deny
Deny from all

Lav så dit downloadscript i roden, i.e. /download.php med indholdet:

<?php

    session_start();
    // Check evt. her om man er logget ind med en session
    $sep = DIRECTORY_SEPARATOR;
    $root = realpath( "." ) . $sep . "docs";
   
    if ( !empty( $_GET['file'] ) )
    {
        $filepath = realpath( $root . $sep . $_GET['file'] );
        if ( $root != substr( $filepath, 0, strlen( $root ) ) )
        {
            die( "Ikke tilladt." );
        }
        else
        {
            header( "Cache-control: private" );
            header( "Expires: Mon, 26 Jul 1997 00:00:42 GMT" );
            header( "Last-Modified: " . gmdate( "D, d M Y H:i:s" ) . " GMT" );
            header( "Cache-Control: no-store, no-cache, must-revalidate" );
            header( "Cache-Control: post-check=0, pre-check=0", false );
            header( "Pragma: no-cache" );
            header( "Content-Type: application/octet-stream" );
            header( "Content-Transfer-Method: Binary" );
            header( "Content-Length: " . filesize( $filepath ) );
            header( "Content-Disposition: attachment; filename='" . basename( $filepath ) . "'" );
            readfile( $filepath );
        }
    }

?>

Lige efter session_start() kan du lave et check om folk er logget ind med en alm. session :)

Der er en del indbygget sikkerhed i min ;)
Avatar billede coderdk Praktikant
29. marts 2007 - 17:59 #4
Avatar billede larma Nybegynder
29. marts 2007 - 20:19 #5
Jeg har tatt utgangspunkt i coderdk sitt eksempel ettersom jeg tror jeg må benytte meg av "url request". Men jeg har en side fra før som lister alle mappene samt de underliggende dokumentene i de forskjellige mappene. Og jeg har derfor lavet en funksjon av ditt eksempel coderdke, og denne funksjonen ligger i en ekstern fil. Jeg har ikke lavet store forandringene enda, men har lige noen spørsmål...

function download($file){
  $sep = DIRECTORY_SEPARATOR;
  $root = realpath( "." ) . $sep . "dokomenter";
   
    return $file;
  if (!empty($file))
  {
      $filepath = realpath($root . $sep . $file);
    }
      if ( $root != substr($filepath, 0, strlen( $root)))
      {
          die( "Ikke tilladt." );
      }
      else
      {
          header( "Cache-control: private" );
          header( "Expires: Mon, 26 Jul 1997 00:00:42 GMT" );
          header( "Last-Modified: " . gmdate( "D, d M Y H:i:s" ) . " GMT" );
          header( "Cache-Control: no-store, no-cache, must-revalidate" );
          header( "Cache-Control: post-check=0, pre-check=0", false );
          header( "Pragma: no-cache" );
          header( "Content-Type: application/octet-stream" );
          header( "Content-Transfer-Method: Binary" );
          header( "Content-Length: " . filesize( $filepath ) );
          header( "Content-Disposition: attachment; filename='" . basename( $filepath ) . "'" );
          readfile( $filepath );
      }
  }
}
parameteren sender inn hentes fra linken til dokumentet som blir trykket på, og hentes via $_GET['file']. Og kan f.ex se sådan ud mappe/mappe/test.doc. Og jeg har prøvet meg litt frem ved å returnere det forskjellige variablene for å se hva verdi de får og sånn som $filepath = realpath($root . $sep . $file); ser ikke ud til å gi $filepath noen verdi? Og er det evt. noen andre forandringer jeg børr gjøre med tanke på min metode?

btw genereres funksjonen fra siden som lister mapper og dokumenter på den her måde:
if(isset($_GET['file'])){
  download($_GET['file']);
}

Og takk for hjelp så langt :)

Mvh
Lars
Avatar billede coderdk Praktikant
29. marts 2007 - 21:03 #6
Hvis $filepath ikke får nogen værdi, er det fordi at stien ikke er gyldig... prøv lige efter $fillepath = at skrive:

echo "Testing " . $root . $sep . $file . "<br>";
if ( !is_file( $root . $sep . $file ) || !is_readable( $root . $sep . $file ) )
{
  echo $root . $sep . $file . " is either not a file, or not readable...";
}
Avatar billede coderdk Praktikant
29. marts 2007 - 21:04 #7
Altså på linjen efter, ikke efter = heheh
Avatar billede larma Nybegynder
29. marts 2007 - 23:13 #8
Arg, jeg fant feilen. Jeg hadde skrevet dokomenter istedet for dokumenter. Så nå "finner" den dokumentet, men jeg har ikke muligheten får å lige åpne dokumentet for å kigge på det, jeg må gemme det først. Jeg hadde ønske å kunne lige velge åpne.

Vet ikke om det skal have noget å si, men stien som $root = realpath( "." ) . $sep . "dokomenter"; genererer er sånn:
/var/www/minside.dk/dokumenter/test.doc

I stedet for sånn den var før når jeg åpnet dokumentene og ikke "brugte" .htaccess:
http://minside.dk/dokumenter/test.dk
Avatar billede coderdk Praktikant
29. marts 2007 - 23:44 #9
Prøv for sjov at fjerne

header( "Content-Type: application/octet-stream" );

og ændre:

header( "Content-Disposition: attachment; filename='" . basename( $filepath ) . "'" );

til

header( "Content-Disposition: inline; filename='" . basename( $filepath ) . "'" );
Avatar billede larma Nybegynder
29. marts 2007 - 23:53 #10
Jeg vil bare legge til at jeg har fått amews_aj sin versjon til å virke i både explorer og opera når den ser sådan ud:
function download($file){
  $filnavn = $file;

    $file_path = $_SERVER['DOCUMENT_ROOT'] . "/dokumenter/" . $filnavn;
  if (file_exists($file_path) && $filnavn != "" ) {
      header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
      header("Content-Type: application/octet-stream");
      header("Content-Length: " . filesize($file_path));
            header("Content-Disposition: attachment; filename=".basename( $filnavn )."");
      readfile($file_path);
  }else{
      echo "Filen findes ikke!";
  }
}
Din versjon coderdk, har jeg fått til å virke i opera browseren men ikke i explorer, den forsøker å åpne dokumentet i word, men får beskjed om at den ikke finner filen. Den ser for øyeblikket sådan ud:
function download($file){

  $sep = DIRECTORY_SEPARATOR;
  $root = realpath( "." ) . $sep . "dokumenter";

  if (!empty($file))
  {
      $filepath = realpath($root . $sep . $file);

      if ( $root != substr($filepath, 0, strlen( $root)))
      {
          die( "Ikke tilladt." );
      }
      else
      {
          header( "Cache-control: private" );
          header( "Expires: Mon, 26 Jul 1997 00:00:42 GMT" );
          header( "Last-Modified: " . gmdate( "D, d M Y H:i:s" ) . " GMT" );
          header( "Cache-Control: no-store, no-cache, must-revalidate" );
          header( "Cache-Control: post-check=0, pre-check=0", false );
          header( "Pragma: no-cache" );
          header( "Content-Type: application/octet-stream" );
          header( "Content-Transfer-Method: Binary" );
          header( "Content-Length: " . filesize( $filepath ) );
          header( "Content-Disposition: attachment; filename=" . basename( $filepath ) . "" );
          readfile( $filepath );
      }
  }
}
På din så forandret jeg lige
header( "Content-Disposition: attachment; filename="' . basename( $filepath ) . "'" );
til:
header( "Content-Disposition: attachment; filename=" . basename( $filepath ) . "" );

Jeg fjernet altså bare to ' i filename=" . basename( $filepath ) . "".

Så jeg vet ikke om du kan gjennomskue hva som gjør at din versjon ikke virker i explorer sammenlignet med amews_aj sin? Jeg vet for lite om "header informasjonen"
Avatar billede larma Nybegynder
29. marts 2007 - 23:58 #11
Jeg forsøkte ditt forslag med å fjerne en linje og bytte ud en. Og da fikk jeg bare en hel del kryptiske tegn på skjermen ;)
Avatar billede coderdk Praktikant
30. marts 2007 - 01:26 #12
Prøv ændre, så der kun står disse header()-kald:

          header( "Expires: Mon, 26 Jul 1997 00:00:42 GMT" );
          header( "Last-Modified: " . gmdate( "D, d M Y H:i:s" ) . " GMT" );
          header( "Cache-Control: no-store, no-cache, must-revalidate" );
          header( "Content-Type: application/octet-stream" );
          header( "Content-Length: " . filesize( $filepath ) );
          header( "Content-Disposition: attachment; filename=" . basename( $filepath ) . "" );
          readfile( $filepath );
Avatar billede larma Nybegynder
30. marts 2007 - 10:27 #13
Hej igjen.

Da har jeg forsøkt å byttet ud header()-kaldet med den overnevte, men får samme feilmelding fra word når jeg forsøker å åpne via exploerer. Men det kan de ut som det er denne linjen som laver balader:

header( "Cache-Control: no-store, no-cache, must-revalidate" );

For når jeg bytter den overstående med den underståend så virker det:

header("Cache-Control: must-revalidate, post-check=0, pre-check=0");

Jeg vet ikke om den header'en (nr 1) bør være med, om det er mulig å gjøre noen forandringer på den sånn at det virker med den?
Avatar billede larma Nybegynder
10. april 2007 - 11:24 #14
Har du noen formening om linjen header( "Cache-Control: no-store, no-cache, must-revalidate" ); bør være med coderdk? Post et svar iallfall, sånn at du kan få dine points for hjelpen.
Avatar billede coderdk Praktikant
10. april 2007 - 11:45 #15
Jeg tror nu godt at den virker uden linjen - Jeg mener også at der er en af de linjer der kan skabe problemer i nogle browsere... Anyway, tag nogle point selv også :D
Avatar billede larma Nybegynder
10. april 2007 - 23:33 #16
Ok, takk for svar og hjelp med å løse oppgaven. Om jeg får et svar fra amews_aj også, så skal han få noen av pointsene, ettersom han også kom med en løsning som virket etter mine behov. Så da venter jeg litt for å se om han kommer med et svar, ellers får du alle pointsene.
Avatar billede coderdk Praktikant
11. april 2007 - 00:08 #17
Cool :) Hvis du brugte hans, burde du give ham pointene :)
Avatar billede amews_aj Nybegynder
11. april 2007 - 09:18 #18
Hvis du direkte brugte mit forslag må du da gerne give mig lidt point, men hvis du fulgte coderdk's beskrivelser, så giv ham dem ;)

Giv dem til den som hjalp dig til det endelige resultat.
(Her er et svar fra mig, hvis du har kunnet bruge min hjælp) ;)
Avatar billede larma Nybegynder
11. april 2007 - 09:33 #19
Jeg har i grunn utviklet min "egen" løsning ved bruk av deres forslag. Men ettersom coderdk har vært behjelpelig og brukt litt mer tid på å få enkelte deler av hans forslag til å virke etter mine behov, ønsker jeg å gi han litt mer points. Håper poengfordelingen er ok for dere. Og igjen takk for hjelp.
Avatar billede larma Nybegynder
11. april 2007 - 09:36 #20
Lort, jaja, nå var det meningen at coderdk skulle få 40 points og arnews_aj 20, men jeg trykket forkert :/ Håper det går fint at dere fikk 30 points hver.
Avatar billede coderdk Praktikant
11. april 2007 - 11:44 #21
Helt fint med mig :)
Avatar billede amews_aj Nybegynder
11. april 2007 - 14:59 #22
Heller ikke noget problem her ;)
Jeg er ikke en af dem der går vildt meget op i point :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester



IT-JOB

Fonden DBK

.Net/C#-udviklere

Cognizant Technology Solutions Denmark ApS

Test Manager

Cognizant Technology Solutions Denmark ApS

Data Architect

Netcompany A/S

Software Developer