现在很多项目的图片信息比较重要,但是目前大多数情况下,图片的访问都是通过img的src属性来直接访问,这样访问直接通过服务器的图片地址访问到图片,类似于(https://192.168.1.122/feed/pictrue.png),如果把这个链接发给任何一个人,都可以直接访问,很容易被人非法盗链
下面使用PHP的画布来解决这个问题,实现的思路,把图片显示交给PHP来处理,把真实的访问地址隐藏起来。
用户查看图片先要经过PHP,(如还没登录,那么不允许查看),在用户有权限的时候可以查看。同时也隐藏了真实的访问地址
访问路径:
//picture.php 重新定义了一个入口
//token_temp 为临时一个授权ID,一般设置为5-10有效
//pic_id 通过这个ID来找到图片的真是路径
源码如下:
session_start();
require_once('include/database/PearDatabase.php');
require_once('include/utils/utils.php');
global $adb;
$adb = PearDatabase::getInstance();
$isattachment = $_REQUEST['isattachment'];
#根据图片的ID获取图片的真是路径
$pic_path = getPicPath($_REQUEST['pic_id']);
#判断用户是否登录
$use_current_login = false;
if($_SESSION["authenticated_user_id"])
{
$use_current_login = true;
}
else{
$token_temp = $_REQUEST['token_temp'];
$token_temp_array = explode('_',$token_temp,2);
if(get_user_token_temp($token_temp_array[0]) == $token_temp){
$_SESSION['authenticated_user_id'] = $token_temp[0];
$_SESSION['authenticated_user_id_is_temp'] = 'true';
$use_current_login = true;
}
}
if($use_current_login){
$n = new imgdata;
$n -> getdir($pic_path); //图片路径,一般存储在数据库里,用户无法获取真实路径,可根据图片ID来获取
$n -> img2data();
$n -> data2img();
}else{
exit('非法盗链');
}
exit;
function getPicPath($crmid){
global $adb;
$module_name = getModuleName($crmid);
$module = CRMEntity::getInstance($module_name);
$table_name = $module->table_name;
$table_index = $module->table_index;
$sql = "SELECT
rush_attachments.path,
rush_attachments.attachmentsid,
rush_attachments.name,
rush_crmentity.setype
FROM
$table_name
LEFT JOIN rush_seattachmentsrel ON rush_seattachmentsrel.crmid = $table_name.$table_index
INNER JOIN rush_attachments ON rush_attachments.attachmentsid = rush_seattachmentsrel.attachmentsid
INNER JOIN rush_crmentity ON rush_crmentity.crmid = rush_attachments.attachmentsid
WHERE rush_crmentity.crmid = $crmid";
$result = $adb->query($sql);
$pic_path = '';
if($adb->num_rows($result)>0){
$rowdata = $adb->raw_query_result_rowdata($result,0);
$pic_path = $adb->query_result($result,0,'path').$adb->query_result($result,0,'attachmentsid').'_'.$rowdata['name'];
}
return $pic_path;
}
function getModuleName($crm_id){
global $adb;
$sql = " select * from rush_crmentity WHERE crmid = $crm_id";
$result = $adb->query($sql);
if($adb->num_rows($result)>0){
$name = $adb->query_result($result,0,'setype');
$res = explode(' ',$name);
if(is_array($res)){
$module_name = $res[0];
}else{
$module_name = $res;
}
}else{
$module_name = '';
}
return $module_name;
}
#测试使用
function dump($data, $is_exit=true)
{
if (!headers_sent()) {
header("Content-type: text/html; charset=utf-8");
}
echo "
\n";
print_r($data);
echo "\n
\n";if ($is_exit) exit();
}
##########################################################################################
#这里把前端的图片给隐藏了,直接使用php 的画布输出
class imgdata{
public $imgsrc;
public $imgdata;
public $imgform;
public function getdir($source){
$this->imgsrc = $source;
if (!file_exists($this->imgsrc)){
global $default_charset;
$this->imgsrc=iconv($default_charset,"gbk//IGNORE", $this->imgsrc);
}
}
public function img2data(){
$this->_imgfrom($this->imgsrc);
return $this->imgdata=fread(fopen($this->imgsrc,'rb'),filesize($this->imgsrc));
}
public function data2img(){
global $isattachment;
ob_clean();
header("content-type:$this->imgform");
if ($isattachment){
$filename=explode('.',$this->imgsrc);
$ext = array_pop($filename);
$Disposition = "filename=image".$ext;
header("Content-Disposition: attachment; " . $Disposition);
}
echo $this->imgdata;
//echo $this->imgform;
//imagecreatefromstring($this->imgdata);
}
public function _imgfrom($imgsrc){
$info=getimagesize($imgsrc);
return $this->imgform = $info['mime'];
}
}
?>
效果图:
image.png