使用PHP get_content获取IP不一致,如何修改wmsAuthSign关联自身IP播放m3u8?
这个问题的核心很明确:wmsAuthSign这个签名是和请求它的IP绑定的——你用PHP的file_get_contents请求时,用的是服务器的公网IP,所以拿到的签名只认服务器IP;而你本地播放时用的是自己的IP,自然和签名不匹配,导致无法播放。
下面给你几个可行的解决方案,按靠谱程度排序:
1. 让前端直接请求生成签名,拿到匹配自身IP的m3u8链接
这是最稳妥的方案。既然签名和请求IP绑定,那就让用户的浏览器(也就是你的本地IP)直接去请求生成wmsAuthSign的接口,拿到对应自己IP的签名后,再拼接成完整的m3u8链接给播放器。
举个简单的前端示例(用JavaScript):
// 假设获取签名的接口是 /get-wms-sign fetch('/get-wms-sign?channel=xxx') .then(res => res.json()) .then(data => { const m3u8Url = `https://example.com/stream.m3u8?wmsAuthSign=${data.sign}`; // 把这个url传给播放器播放 const player = document.getElementById('video-player'); player.src = m3u8Url; });
这里的/get-wms-sign接口只需要返回对应频道的签名就行,不需要服务器去请求m3u8——因为前端请求这个接口时,来源IP就是你的本地IP,接口返回的签名自然和你的IP匹配。
2. 服务器请求时透传用户真实IP(不一定生效)
如果必须要服务器介入请求,你可以尝试在file_get_contents请求时,添加X-Forwarded-For头,把用户的真实IP传递给签名生成服务,让它误以为是用户的IP在请求。
PHP代码示例:
// 获取用户的真实IP(注意如果有反向代理的话要调整) $userRealIp = $_SERVER['REMOTE_ADDR']; // 如果用了CDN或反向代理,可能需要取X-Forwarded-For // $userRealIp = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']; // 创建请求上下文,添加X-Forwarded-For头 $context = stream_context_create([ 'http' => [ 'header' => "X-Forwarded-For: $userRealIp\r\n" ] ]); // 用这个上下文请求签名或m3u8链接 $m3u8Content = file_get_contents($yourM3u8Url, false, $context);
⚠️ 注意:这个方法不一定管用,因为很多签名服务会直接读取TCP连接的真实IP(也就是你的服务器IP),而不会信任X-Forwarded-For头——毕竟这个头很容易伪造。所以只有当签名生成服务明确支持通过这个头识别客户端IP时,这个方法才有效。
3. 修改签名生成规则(仅适用于可控服务)
如果这个m3u8服务是你自己开发的,或者你能修改签名生成的逻辑,那可以直接去掉IP绑定的限制,或者允许在请求签名时指定IP参数,这样服务器就能生成对应你本地IP的签名了。但如果是第三方服务的话,这个方法就没法用了。
总的来说,优先选第一种方案,让前端直接请求签名,这样从根源上解决了IP不匹配的问题。
内容的提问来源于stack exchange,提问作者Zabi

