Downloaden bestanden middels de headers een probleem door sessie
Ik heb de tutorial gebruikt op deze website om een directory te beveiligen en de bestanden welke daarin staan alleen toegankelijk te maken voor mensen welke zijn ingelogd. http://www.phphulp.nl/php/tutorial/beveiliging/downloads-beveiligen/263/de-laatste-stap/484/
Het script werkt, echter alleen bij .doc bestanden en .xls bestanden.
De downloads staan in de map verenigingsdocumenten. Deze is afgeschermd middels de .htaccess welke ook in de tutorial staat.
De modrewrite ziet er momenteel als volgt uit:
Code (php)
1
2
3
2
3
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/downloadbestand/.*$
RewriteRule ^.*$ /bestanddownloaden.php?uri=%{REQUEST_URI}
RewriteCond %{REQUEST_URI} ^/downloadbestand/.*$
RewriteRule ^.*$ /bestanddownloaden.php?uri=%{REQUEST_URI}
Dit werkt allemaal naar toebehoren.
bestanddownloaden.php
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<?php session_start();
ini_set('display_errors', 'On');
error_reporting(E_ALL);
//Deze regel is belangrijk! Verwijder deze regel niet, anders werkt het downloaden in IE niet goed meer.
session_cache_limiter('private');
//Deze pagina zorgt ervoor dat een bestand wel gedownload kan worden indien men ingelogd is. Direct een bestandsnaam intypen en dan downloaden kan dus niet meer.
if(!isset($_GET['uri']) || empty($_GET['uri']))
{
echo "Geen url opgegeven!";
exit();
}
//Volledige bestandsnaam en de bijbehorende mappen ophalen.
if(isset($_GET['uri']))
{
$bestandsmap = $_GET['uri'];
}
else
{
$bestandsmap = '';
}
$bestandsmap = substr($bestandsmap, 1);
//Kijken wat de bestandsnaam is.
$file = substr($_GET['uri'], strrpos($_GET['uri'],"/")+1);
$bestandsmapindelen = explode("/",$bestandsmap);
//Een check of de map welke getoond moet worden wel gezien mag worden. De hoofdmap en daarin alle submappen mag alleen getoont worden, in dit geval verenigingsdocumenten. Als de eerste map in de url niet verenigingsdocumenten is dan wordt deze gewoon daarop gezet.
$folder = '';
if($bestandsmapindelen[1] != 'verenigingsdocumenten')
{
$folder = 'verenigingsdocumenten/';
}
$aantal_bestandsmapindelen = count($bestandsmapindelen);
$teller = 1;
while(($aantal_bestandsmapindelen-1) > $teller)
{
$folder .= $bestandsmapindelen[$teller].'/';
$teller = $teller + 1;
}
$file = htmlspecialchars($file);
if(!file_exists($folder.'/'.$file))
{
echo "Bestand bestaat niet!";
exit();
}
$mime = mime_content_type($folder.'/'.$file);
if(isset($_SESSION['ingelogd']))
{
if($_SESSION['ingelogd'] != 1)
{
echo 'Geen toegang';
exit();
}
}
else
{
echo 'Session niet bekend. '.$mime.'<br/>';
exit();
}
header("Content-Type: ".$mime);
header("Content-Length: ".filesize($folder.'/'.$file));
header("Content-Disposition: attachement; filename=".$file);
header("Content-Transfer-Encoding: binary");
$fp = fopen($folder.'/'.$file,"r");
fpassthru($fp);
fclose($fp);
?>
ini_set('display_errors', 'On');
error_reporting(E_ALL);
//Deze regel is belangrijk! Verwijder deze regel niet, anders werkt het downloaden in IE niet goed meer.
session_cache_limiter('private');
//Deze pagina zorgt ervoor dat een bestand wel gedownload kan worden indien men ingelogd is. Direct een bestandsnaam intypen en dan downloaden kan dus niet meer.
if(!isset($_GET['uri']) || empty($_GET['uri']))
{
echo "Geen url opgegeven!";
exit();
}
//Volledige bestandsnaam en de bijbehorende mappen ophalen.
if(isset($_GET['uri']))
{
$bestandsmap = $_GET['uri'];
}
else
{
$bestandsmap = '';
}
$bestandsmap = substr($bestandsmap, 1);
//Kijken wat de bestandsnaam is.
$file = substr($_GET['uri'], strrpos($_GET['uri'],"/")+1);
$bestandsmapindelen = explode("/",$bestandsmap);
//Een check of de map welke getoond moet worden wel gezien mag worden. De hoofdmap en daarin alle submappen mag alleen getoont worden, in dit geval verenigingsdocumenten. Als de eerste map in de url niet verenigingsdocumenten is dan wordt deze gewoon daarop gezet.
$folder = '';
if($bestandsmapindelen[1] != 'verenigingsdocumenten')
{
$folder = 'verenigingsdocumenten/';
}
$aantal_bestandsmapindelen = count($bestandsmapindelen);
$teller = 1;
while(($aantal_bestandsmapindelen-1) > $teller)
{
$folder .= $bestandsmapindelen[$teller].'/';
$teller = $teller + 1;
}
$file = htmlspecialchars($file);
if(!file_exists($folder.'/'.$file))
{
echo "Bestand bestaat niet!";
exit();
}
$mime = mime_content_type($folder.'/'.$file);
if(isset($_SESSION['ingelogd']))
{
if($_SESSION['ingelogd'] != 1)
{
echo 'Geen toegang';
exit();
}
}
else
{
echo 'Session niet bekend. '.$mime.'<br/>';
exit();
}
header("Content-Type: ".$mime);
header("Content-Length: ".filesize($folder.'/'.$file));
header("Content-Disposition: attachement; filename=".$file);
header("Content-Transfer-Encoding: binary");
$fp = fopen($folder.'/'.$file,"r");
fpassthru($fp);
fclose($fp);
?>
verenigingsdocumenten.php
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
<?php
if(isset($_GET['map']))
{
$bestandsmap = $_GET['map'];
}
else
{
$bestandsmap = 'verenigingsdocumenten';
}
//De laatste / achter de map naam moet pleiter omdat dit het systeem vernaggeld. Met de volgende functie haalt hij deze laatste slash eraf.
if(substr($bestandsmap, -1) == '/')
{
$bestandsmap = substr($bestandsmap, 0, -1);
}
//Een check of de map welke getoond moet worden wel gezien mag worden. De hoofdmap en daarin alle submappen mag alleen getoont worden, in dit geval verenigingsdocumenten. Als de eerste map in de url niet verenigingsdocumenten is dan wordt deze gewoon daarop gezet.
$bestandsmapindelen = explode("/",$bestandsmap);
if($bestandsmapindelen[0] != 'verenigingsdocumenten')
{
$bestandsmap = 'verenigingsdocumenten';
}
//De bovenliggende map berekenen
$aantalmapdelen = count($bestandsmapindelen);
$teller = 0;
while($teller <= ($aantalmapdelen-2))
{
$bovenliggendemap .= $bestandsmapindelen[$teller].'/';
$teller = $teller + 1;
}
//bestandsextencies die weergeven worden, ze moeten door kommas gescheiden worden!
$filters = array("xls","xlsx","doc","docx","zip","rar","pdf","bmp","jpg","jpeg","png","ppt","pptx","txt","gif");
echo'
<div class="blokmiddeninhoud">
<div class="bloktitel">
<div class="bloktiteltekst"><img src="afbeeldingen/icon.png" alt="logo klein" class="icoon" /><h2>Verenigingsdocumenten</h2></div>
</div>
<div class="blokinhoud">
';
echo'<h1>'.ucfirst($bestandsmap).'</h1>';
if(isset($bovenliggendemap))
{
echo '<a href="portal.php?pagina=verenigingsdocumenten&map='.$bovenliggendemap.'">Map omhoog</a><br/><br/>';
}
echo '
<table class="overzichtstabel" style="width: 550px;">
<tr><td style="width: 30px;"></td><td style="width: 320px;"><b>Bestand</b></td><td style="width: 200px;"><b>Laatst gewijzigd</b></td></tr>
';
// hier de loop voor de links
$uitlees= opendir($bestandsmap);
$bestanden= array();
if (!$filters)
{
while(($file = readdir($uitlees))!==false)
{
$bestanden[] = $file;
}
}
else
{
while (($dit_bestand = readdir($uitlees))!==false)
{
// herhaal volgende opdrachten voor elk bestand uit $uitlees
$type = array_pop(explode(".",$dit_bestand)); //neem de letters na het laatste punt van de bestandsnaam
//Hier zet ik de voorgaande map van het bestand of de map ervoor omdat anders de functie is_dir een map niet herkent als map, nu wel. Daarnaast haal ik de mappen . en .. eruit, dit zijn geen echte mappen.
$bestandsnaammetmap = "".$bestandsmap ."/". $dit_bestand."";
if(is_dir($bestandsnaammetmap) AND $dit_bestand != '.' && $dit_bestand != '..')
{
//Als een waarde een map is wordt deze toegevoegd aan de mappen array.
$mappen[] = $dit_bestand;
}
if(is_file($bestandsnaammetmap))
{
//Als een waarde een bestand is wordt vervolgens gechecked of deze een toegestane extensie heeft.
if(in_array($type, $filters))
{
//als de extensie voorkomt in de array dan ...
$bestanden[] = $dit_bestand;
}
}
}
}
sort($mappen);
sort($bestanden);
foreach($mappen as $map)
{
if(is_int($teller/2))
{
$getal = 1;
}
else
{
$getal = 2;
}
echo '<tr class="tabelomenomkleur'.$getal.'"><td style="width: 30px;"><img src="afbeeldingen/bestandspictogrammen/map.png" /></td><td style="width: 320px;"><a href="portal.php?pagina=verenigingsdocumenten&map='.$bestandsmap.'/'.$map.'" class="donkerblauw">'.$map.'</a></td><td style="width: 200px;">20-04-30</td></tr>';
$teller = $teller +1;
}
foreach($bestanden as $bestand)
{
if(is_int($teller/2))
{
$getal = 1;
}
else
{
$getal = 2;
}
$bestandsnaambestand = explode(".",$bestand);//Neem de bestandsnaam zonder extensie
$aantaldelen_bestandsnaambestand = count($bestandsnaambestand);
$bestandsnaamzonderextensie = $bestandsnaambestand[0];
$extensie = $bestandsnaambestand[$aantaldelen_bestandsnaambestand-1];
echo '<tr class="tabelomenomkleur'.$getal.'"><td style="width: 30px;"><img src="afbeeldingen/bestandspictogrammen/'.$extensie.'.png" /></td><td style="width: 320px;"><a href="downloadbestand/'.$bestandsmap.'/'. $bestand .'" class="donkerblauw">'.$bestandsnaamzonderextensie.'</a></td><td style="width: 200px;">20-04-30</td></tr>';
$teller = $teller +1;
}
closedir($uitlees);
echo'
</table>
<br/>
</div>
</div>
';
?>
if(isset($_GET['map']))
{
$bestandsmap = $_GET['map'];
}
else
{
$bestandsmap = 'verenigingsdocumenten';
}
//De laatste / achter de map naam moet pleiter omdat dit het systeem vernaggeld. Met de volgende functie haalt hij deze laatste slash eraf.
if(substr($bestandsmap, -1) == '/')
{
$bestandsmap = substr($bestandsmap, 0, -1);
}
//Een check of de map welke getoond moet worden wel gezien mag worden. De hoofdmap en daarin alle submappen mag alleen getoont worden, in dit geval verenigingsdocumenten. Als de eerste map in de url niet verenigingsdocumenten is dan wordt deze gewoon daarop gezet.
$bestandsmapindelen = explode("/",$bestandsmap);
if($bestandsmapindelen[0] != 'verenigingsdocumenten')
{
$bestandsmap = 'verenigingsdocumenten';
}
//De bovenliggende map berekenen
$aantalmapdelen = count($bestandsmapindelen);
$teller = 0;
while($teller <= ($aantalmapdelen-2))
{
$bovenliggendemap .= $bestandsmapindelen[$teller].'/';
$teller = $teller + 1;
}
//bestandsextencies die weergeven worden, ze moeten door kommas gescheiden worden!
$filters = array("xls","xlsx","doc","docx","zip","rar","pdf","bmp","jpg","jpeg","png","ppt","pptx","txt","gif");
echo'
<div class="blokmiddeninhoud">
<div class="bloktitel">
<div class="bloktiteltekst"><img src="afbeeldingen/icon.png" alt="logo klein" class="icoon" /><h2>Verenigingsdocumenten</h2></div>
</div>
<div class="blokinhoud">
';
echo'<h1>'.ucfirst($bestandsmap).'</h1>';
if(isset($bovenliggendemap))
{
echo '<a href="portal.php?pagina=verenigingsdocumenten&map='.$bovenliggendemap.'">Map omhoog</a><br/><br/>';
}
echo '
<table class="overzichtstabel" style="width: 550px;">
<tr><td style="width: 30px;"></td><td style="width: 320px;"><b>Bestand</b></td><td style="width: 200px;"><b>Laatst gewijzigd</b></td></tr>
';
// hier de loop voor de links
$uitlees= opendir($bestandsmap);
$bestanden= array();
if (!$filters)
{
while(($file = readdir($uitlees))!==false)
{
$bestanden[] = $file;
}
}
else
{
while (($dit_bestand = readdir($uitlees))!==false)
{
// herhaal volgende opdrachten voor elk bestand uit $uitlees
$type = array_pop(explode(".",$dit_bestand)); //neem de letters na het laatste punt van de bestandsnaam
//Hier zet ik de voorgaande map van het bestand of de map ervoor omdat anders de functie is_dir een map niet herkent als map, nu wel. Daarnaast haal ik de mappen . en .. eruit, dit zijn geen echte mappen.
$bestandsnaammetmap = "".$bestandsmap ."/". $dit_bestand."";
if(is_dir($bestandsnaammetmap) AND $dit_bestand != '.' && $dit_bestand != '..')
{
//Als een waarde een map is wordt deze toegevoegd aan de mappen array.
$mappen[] = $dit_bestand;
}
if(is_file($bestandsnaammetmap))
{
//Als een waarde een bestand is wordt vervolgens gechecked of deze een toegestane extensie heeft.
if(in_array($type, $filters))
{
//als de extensie voorkomt in de array dan ...
$bestanden[] = $dit_bestand;
}
}
}
}
sort($mappen);
sort($bestanden);
foreach($mappen as $map)
{
if(is_int($teller/2))
{
$getal = 1;
}
else
{
$getal = 2;
}
echo '<tr class="tabelomenomkleur'.$getal.'"><td style="width: 30px;"><img src="afbeeldingen/bestandspictogrammen/map.png" /></td><td style="width: 320px;"><a href="portal.php?pagina=verenigingsdocumenten&map='.$bestandsmap.'/'.$map.'" class="donkerblauw">'.$map.'</a></td><td style="width: 200px;">20-04-30</td></tr>';
$teller = $teller +1;
}
foreach($bestanden as $bestand)
{
if(is_int($teller/2))
{
$getal = 1;
}
else
{
$getal = 2;
}
$bestandsnaambestand = explode(".",$bestand);//Neem de bestandsnaam zonder extensie
$aantaldelen_bestandsnaambestand = count($bestandsnaambestand);
$bestandsnaamzonderextensie = $bestandsnaambestand[0];
$extensie = $bestandsnaambestand[$aantaldelen_bestandsnaambestand-1];
echo '<tr class="tabelomenomkleur'.$getal.'"><td style="width: 30px;"><img src="afbeeldingen/bestandspictogrammen/'.$extensie.'.png" /></td><td style="width: 320px;"><a href="downloadbestand/'.$bestandsmap.'/'. $bestand .'" class="donkerblauw">'.$bestandsnaamzonderextensie.'</a></td><td style="width: 200px;">20-04-30</td></tr>';
$teller = $teller +1;
}
closedir($uitlees);
echo'
</table>
<br/>
</div>
</div>
';
?>
Wanneer ik uit bestanddownloaden.php de sessie met daarin de check of mensen zijn ingelogd weg haal dan werkt het script naar behoren. De headers zijn dus blijkbaar al verzonden of kunnen in ieder geval niet samenwerken met $_SESSION. Ik wil echter wel eerst verifiëren of mensen het bestand mogen downloaden.
Ik maak gebruik van PHP Version 5.3.2.
Echt hulde voor diegene die me kan helpen, het heeft me nu al 2 dagen van me leven gekost.
Gewijzigd op 14/08/2011 19:16:35 door Kees de braak
Begin je script met controle. Indien ingelogd --> ga verder. Anders --> exit.
Ik had het eerst allemaal in een if clausule staan op deze manier had ik beter inzicht waar het probleem ligt. Dank voor je tip, als het werkt dan gaat het inderdaad op jouw manier.