PHP通过Discord OAuth2获取JPEG用户头像实现及CDN文档疑问咨询
PHP环境下Discord OAuth2获取固定格式JPEG用户头像实现方案
先修正你现有授权代码的问题
你现在写的授权请求代码里把size=16作为参数传到OAuth2授权接口是完全无效的,授权端点根本不识别这类和授权逻辑无关的参数,加了也会被Discord服务端直接丢弃。这个尺寸参数是头像CDN接口的专属参数,不是授权流程的参数。
核心实现逻辑
整个流程不需要本地做图片格式转换,直接利用Discord CDN的内置格式控制能力就能实现「不管原用户头像是不是GIF,都拿到JPEG格式图片」的需求:
- 走完OAuth2授权流程,拿到access_token之后,调用带有
identifyscope权限的用户信息接口,获取用户的Discord ID和头像哈希值 - 按照Discord CDN的规则拼接头像地址,只要在头像哈希后面加上
.jpg作为扩展名,Discord CDN会自动将原图(包括GIF动图)转为静态JPEG格式输出,不需要额外处理 - 尺寸参数按照官方要求加在CDN地址的查询字符串里即可,取值必须是16-4096区间内的2的整数次幂。
可直接运行的代码示例
修正后的授权请求发起代码
$params = array( 'client_id' => OAUTH2_CLIENT_ID, 'redirect_uri' => 'http://localhost:80/dwayne', 'response_type' => 'code', 'scope' => 'identify guilds email', ); header('Location: https://discord.com/api/oauth2/authorize?' . http_build_query($params)); die();
授权回调阶段的头像地址生成代码
// 从回调参数中获取授权码 $code = $_GET['code'] ?? ''; // 第一步:用授权码交换access_token $tokenRequest = stream_context_create([ 'http' => [ 'method' => 'POST', 'header' => 'Content-Type: application/x-www-form-urlencoded', 'content' => http_build_query([ 'client_id' => OAUTH2_CLIENT_ID, 'client_secret' => OAUTH2_CLIENT_SECRET, 'grant_type' => 'authorization_code', 'code' => $code, 'redirect_uri' => 'http://localhost:80/dwayne', ]) ] ]); $tokenData = json_decode(file_get_contents('https://discord.com/api/oauth2/token', false, $tokenRequest), true); $accessToken = $tokenData['access_token'] ?? ''; // 第二步:拉取授权用户的基础信息 $userRequest = stream_context_create([ 'http' => [ 'header' => "Authorization: Bearer $accessToken" ] ]); $userInfo = json_decode(file_get_contents('https://discord.com/api/users/@me', false, $userRequest), true); // 第三步:生成固定JPEG格式的头像地址 $userId = $userInfo['id']; $avatarHash = $userInfo['avatar']; // 配置需要的头像尺寸,必须是2的整数次幂 $avatarSize = 256; if ($avatarHash) { // 强制指定.jpg扩展名,哪怕原头像为GIF格式,CDN也会输出静态JPEG $avatarUrl = "https://cdn.discordapp.com/avatars/{$userId}/{$avatarHash}.jpg?size={$avatarSize}"; } else { // 用户未设置自定义头像时,走默认头像逻辑,同样指定JPEG输出 $defaultAvatarIndex = ($userId >> 22) % 6; $avatarUrl = "https://cdn.discordapp.com/embed/avatars/{$defaultAvatarIndex}.jpg?size={$avatarSize}"; }
关键注意事项
- 不需要对原GIF头像做本地转码:Discord的自定义GIF头像的哈希值通常以
a_开头,这类头像不管原格式是什么,只要在URL里指定.jpg扩展名,CDN会自动取GIF第一帧转为静态JPEG输出 - 尺寸参数仅对CDN地址生效,不要添加到OAuth2授权请求、用户信息接口请求的参数里
- 默认头像的生成逻辑不需要额外拼接复杂规则,按照Discord返回的默认头像ID直接加
.jpg扩展名即可拿到JPEG格式图片 - 所有接口请求请做好异常捕获,避免因网络问题、token失效导致的代码报错
内容的提问来源于stack exchange,提问作者UrTech Tips
相关产品推荐
相关产品推荐

