【发布时间】:2015-11-07 21:08:09
【问题描述】:
我设置了一些安全措施,不允许用户从我的网站下载 MP3。 Ajax 发送一个一次性下载令牌的请求,该令牌附加到我输入 soundmanager2 的 URL。除了在 Safari 中,此安全性工作正常。
前端请求
streamSong: function(song)
{
$.ajax({
url: '/streamsong/'+song.id,
type: 'get',
success: function(token) {
var stream = '/streamsong/'+song.id+'/'+token;
Player.sendSongToPlayer(song, stream);
}
});
}
路线
Route::get('/streamsong/{id}/{token?}', 'StreamController@setupStream');
控制器
class StreamController extends Controller {
public function setupStream($id, $token = null)
{
$stream = new Stream();
if ($token == null) {
if (Request::ajax()) {
$sessionToken = $stream->setToken(str_random(40));
return response($sessionToken);
} else {
return 'no way jose';
}
}
if ($token == $stream->getToken() ) {
return($stream->sendStream($id));
}
}
}
流类
public function setToken($token)
{
Session::flash('songToken', $token);
return($token);
}
public function getToken()
{
$token = Session::get('songToken');
return($token);
}
public function sendStream($id)
{
$post = Post::find($id);
$pathToFile = base_path().'/storage/app/mp3/'.$post->song_path;
$fileSize = filesize($pathToFile);
$name = $post->song_path;
$headers = array(
'Content-Type'=>'audio/mpeg',
'Pragma'=>'public',
'Content-Transfer-Encoding' => 'binary',
'Expires'=> 0,
'Cache-Control'=> 'must-revalidate, post-check=0, pre-check=0',
'Filename'=>$name,
'Content-Length'=>$fileSize,
'Connection'=> 'keep-alive'
);
return response()->download($pathToFile, $name, $headers);
}
我得出的唯一结论是 Safari 发出了多个文件下载请求,因此令牌在第一次尝试时就被销毁了。但是,我在时间线控制台中只看到一个 GET 请求。如果我将 Session::flash 设置为 Session::set 它在 Safari 中可以正常工作,但这会绕过安全措施。即使使用 Session::set 在发送下载响应之前我也无法删除会话令牌变量,这似乎很奇怪。
还有其他人在 Safari 中遇到过这样的行为吗?我对此感到很困惑。
【问题讨论】:
标签: php session laravel safari