iT邦幫忙

0

[php] header轉址 session 判別

php
  • 分享至 

  • xImage

大家好:

因為不想要讓使用者知道檔案直接的路徑,所以用get的方式從b.php直接下載檔案
首先是用確認UID的session有無值,沒值就轉址,有值再比對使用者ip對不對,如果使用者把連結傳給別人,ip不對也會轉址。

現在遇到問題是使用者已經login,UID有值,所以可以直接下載檔案,但是如果使用者把a.php的連結貼到另一個瀏覽器,UID應該是沒值就不能下載,直接轉址。

測試好像是header($reff);的關係,如果單純打echo文字的話,使用者貼在另一個瀏覽器是可以轉址的,但用改header($reff)使用者的瀏覽器(沒做登入應該UID會沒有值)馬上可以看到直接路徑..

想請問是甚麼問題呢?

謝謝

a.php

<a href="./b.php?type=bclass&files=20201106.jpg&id=192.168.1.1" target="_blank" download="2020/11/06 16:33">可點檔案確認</a>

b.php


<?php

session_start();
if(empty($_SESSION['UID'])){

header("Location:login.php");

}?>

<?php

function get_ip(){

if (!empty($_SERVER["HTTP_CLIENT_IP"])){
    $ip = $_SERVER["HTTP_CLIENT_IP"];
}elseif(!empty($_SERVER["HTTP_X_FORWARDED_FOR"])){
    $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
}else{
    $ip = $_SERVER["REMOTE_ADDR"];
}
     
return $ip;


}
?>

 <?php

  try{
     $filename=$_GET['files'];
     $ipname=$_GET['id']; 
     $filetype=$_GET['type'];   
     
  
     $sqlr="SELECT * FROM feed where jpgdata=:pdfdatan and ip=:ipid";
     $reff="Location: ./uploa/".$filename;

     if(get_ip()==$ipname){

      $conn=new PDO("mysql:host=$hostdb;dbname=$namedb",$userdb,$passdb);
      //echo '資料庫伺服器連線及資料庫開啟成功';
      $conn->exec("SET CHARACTER SET utf8");             
      $sql=$sqlr;
      $result = $conn->prepare($sql);
      $result->execute(array("pdfdatan"=>$filename,"ipid"=>$ipname));
      if($result &&  ($result->rowCount()>0)){   
        header($reff); 

      }
     
     
     else{   
      echo "非上傳者";
      }
      }
      else{
      header('Location:https://www.yahoo.com.tw');  
      }
      }
看更多先前的討論...收起先前的討論...
你說未登入仍沒有自動轉址,那你有確定$_SESSION['UID']裡面真的沒有值嗎
mayyola iT邦研究生 2 級 ‧ 2020-11-06 17:53:18 檢舉
您好:
我將header($reff); 替換純文字測試,貼連結至沒登入過的瀏覽器,是會自動跳轉到login.php 但是若換成header($reff);,一樣的步驟貼連結至沒登入過的瀏覽器,檔案跟直接路徑就馬上顯示在網頁上。
要不要加上exit() 看看 ?
一直不是很明白「我將header($reff); 替換純文字測試」這句話的意思,你的第一段是檢查 session UID,但你一直強調替換 header($reff); 所以很困惑
mayyola iT邦研究生 2 級 ‧ 2020-11-06 18:03:32 檢舉
header("Location:login.php");
下面加exit(); 就好了Q_Q
謝謝!!
mayyola iT邦研究生 2 級 ‧ 2020-11-06 18:13:05 檢舉
耿直小伙您好:我剛剛有檢測session UID在另一個瀏覽器將連結貼上,UID是沒有值的,因為純文字的話,他是可以直接導到login.php 不會再繼續執行下面的語法
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

0
㊣浩瀚星空㊣
iT邦大神 1 級 ‧ 2020-11-06 20:01:54
最佳解答

請注意一下瀏覽器的特性。並確定session的繼承性為何。

一般來說,chroom。另開分頁會重置session id(window open除外)
但ie瀏覽器另開分頁是會被繼承session id。

如果你的session是採用cookie的記錄方式的話。
則瀏覽器都會被繼承居多。(可能吧)

所以在研究你這個問題之前。你得先確定好你的session的情況。再來看是否有問題。

另。跑header並不一定會中斷程式。如果有多個header要特別小心。
一般來說。會盡量只安排一個header。然後用變數來對應url處理。
這樣可以防止週期生命的問題。

千萬不要賭header會轉頁以下程式不會跑的想法。

最後,這個程式碼有非常多需要改善的空間。等我有空閒再看看。

mayyola iT邦研究生 2 級 ‧ 2020-11-10 12:19:36 檢舉

謝謝您提醒..目前都用session處理
但發現html的donwload 好像不能支援對手機跟一些瀏覽器(IE)
測過一些瀏覽器跟手機瀏覽器目前可以直接下載 不知道還有沒有其他漏洞..
有做以下修正,再麻煩您指導 謝謝您

 header('Content-Type: application/force-download');  
 header('Content-Disposition: attachment; filename='. $filen);
 header('Content-Transfer-Encoding: binary');
 header('Expires: 0');
 header('Cache-Control: must-revalidate, post-check=0,   pre-check=0');
header('Pragma: public');
ob_clean();
flush();
readfile($reff);

可以試試加上

header("Content-Length: " .(string)(filesize($filen)) );

然後這一段

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

基本上我會建議拿掉。這段在一般處理json或是文件檔很好用。
不過二進位檔就容易有問題。
大多數來說比較容易碰到記憶體的問題。

另外看到你有用

ob_clean();
flush();

推測你前面程式碼有用了ob之類的東西才需要做這動作。
其實一般我會建議你將下載檔案寫個獨立的控制。
不要跟其它程式碼混用。
這樣你也不需要用ob方式來處理。
可以用一段程式碼來決定好要下載的檔案名稱後。再丟給下載用的model處理。這樣也不用太擔心session的問題。

我要發表回答

立即登入回答