如何通过HTTP Header传递OAuth Access Token适配Battle.Net API变更?
问题描述
暴雪近期更新了Battle.net API的调用规则:禁止在URL查询字符串中传递OAuth Access Token,必须改为在HTTP请求头中以 Authorization: Bearer YOUR_ACCESS_TOKEN 的形式传递。原代码通过URL拼接access_token参数的方式调用API时,触发了HTTP/1.1 401 Unauthorized错误,需修改调用逻辑适配新规则。
现有获取Token代码
function getToken() { $client_id = 'CLIENT ID'; $client_secret = 'CLIENT SECRET'; $url = "https://eu.battle.net/oauth/token"; $params = ['grant_type'=>'client_credentials']; $curl = curl_init(); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_POSTFIELDS, $params); curl_setopt($curl, CURLOPT_USERPWD, $client_id.':'.$client_secret); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($curl)); curl_close($curl); return $result->access_token; } // 调用OAuth2接口获取Token $token = getToken();
现有API调用代码(报错版本)
$filename = 'https://eu.api.blizzard.com/hearthstone/cards?locale=en_US&gameMode=battlegrounds&pageSize=1000&access_token='.$token; $context = stream_context_create(array('http' => array('header'=>'Connection: close '))); $json = file_get_contents($filename,false,$context); $obj = json_decode($json, true); foreach ($obj['cards'] as $k => $cur) { // 检查卡牌是否为新卡牌,不存在于数据库则插入 // INSERT INTO... }
错误信息
Warning: file_get_contents(https://eu.api.blizzard.com/hearthstone/cards?locale=en_US&gameMode=battlegrounds&pageSize=1000&access_token=ACCESS TOKEN): Failed to open stream: HTTP request failed! HTTP/1.1 401 Unauthorized in ****.php on line 155
修改方案
方案1:调整file_get_contents的请求头
移除URL中的access_token参数,将Token放入请求头的Authorization字段:
// 移除URL里的access_token参数 $url = 'https://eu.api.blizzard.com/hearthstone/cards?locale=en_US&gameMode=battlegrounds&pageSize=1000'; // 构造包含Authorization头的请求上下文 $context = stream_context_create([ 'http' => [ 'header' => "Connection: close\r\n" . "Authorization: Bearer {$token}\r\n" ] ]); $json = file_get_contents($url, false, $context); if ($json === false) { die('API请求失败'); } $obj = json_decode($json, true); foreach ($obj['cards'] as $k => $cur) { // 检查卡牌是否为新卡牌,不存在于数据库则插入 // INSERT INTO... }
方案2:改用CURL调用API(推荐,更稳定且便于错误排查)
既然获取Token已经用了CURL,API调用统一用CURL更便于维护:
$url = 'https://eu.api.blizzard.com/hearthstone/cards?locale=en_US&gameMode=battlegrounds&pageSize=1000'; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // 添加Authorization请求头 curl_setopt($curl, CURLOPT_HTTPHEADER, [ "Authorization: Bearer {$token}", "Connection: close" ]); // 可选:若遇到SSL证书验证问题可临时禁用(生产环境不建议) // curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); $json = curl_exec($curl); $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); if ($httpCode !== 200 || $json === false) { die("API请求失败,状态码:{$httpCode}"); } $obj = json_decode($json, true); foreach ($obj['cards'] as $k => $cur) { // 检查卡牌是否为新卡牌,不存在于数据库则插入 // INSERT INTO... }
内容的提问来源于stack exchange,提问作者Jones
相关产品推荐
相关产品推荐

