新创建LinkedIn应用OAuth2.0令牌交换返回invalid_client(401)问询
根据社区机器人分类标记补充详细信息。
精确复现步骤
curl -v -X POST https://www.linkedin.com/oauth/v2/accessToken \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code" \ -d "code=<fresh_authorization_code>" \ -d "client_id=78mo3gtih81ecr" \ -d "client_secret=<freshly_regenerated_secret>" \ -d "redirect_uri=https://www.fashionweekblueprint.com/api/social/oauth/linkedin/callback"
响应
HTTP/2 401 {"error":"invalid_client","error_description":"Client authentication failed"}
已验证无误的项
- Client ID(78mo3gtih81ecr)与LinkedIn开发者平台完全一致,为Auth标签页中的Client ID,而非URL中的应用ID(231638519)。
- 已通过LinkedIn平台“生成”按钮重新生成Client Secret达4次以上,每次生成后数分钟内部署至环境,但所有重新生成操作后仍出现相同错误。
- redirect_uri与应用中注册的授权重定向URL完全匹配(包括无末尾斜杠、协议正确、无查询参数)。
- Content-Type为
application/x-www-form-urlencoded,请求体通过URLSearchParams进行表单编码,而非JSON格式。 - 令牌端点URL为
https://www.linkedin.com/oauth/v2/accessToken(已验证,非api.linkedin.com)。 - OAuth授权步骤(步骤1)成功:用户进入LinkedIn授权界面,完成授权后被重定向回并携带有效的授权码,问题仅出现在步骤2(令牌交换)。
- 请求的权限范围:
openid profile email w_member_social。LinkedIn应用已关联产品:“Sign In with LinkedIn using OpenID Connect”(标准层级)和“Share on LinkedIn”(默认层级),这两个产品可覆盖所有请求的权限范围。 - 应用类型:独立应用。应用ID:231638519。因怀疑之前的应用存在状态损坏,已重新创建全新应用,但仍出现相同错误。
正在验证的特定假设
是否存在LinkedIn端的条件(应用暂停标记、账户层级限制、关联公司验证要求、MS身份绑定)导致令牌交换返回invalid_client,但OAuth授权步骤仍可正常完成?在LinkedIn开发者平台UI中无法复现该状态:应用显示为活跃状态,无警告横幅或暂停提示。
明确的答案(“是,X导致此问题”)或可查看LinkedIn端状态的方法即可解决此问题。无需针对请求格式的调试帮助,请求格式已验证无误。
更新:诊断日志确认请求完全符合LinkedIn规范。尝试使用Basic Auth(RFC 6749 §2.3.1)返回不同错误:HTTP 400“missing client_id”——因此LinkedIn要求通过请求体参数传递凭证。令牌交换请求体中已包含PKCE code_verifier(86字符的无保留字符base64url格式)及client_secret。服务器端环境配置已与LinkedIn平台显示内容完全匹配。Client ID:78mo3gtih81ecr。所有客户端问题已排除,需LinkedIn工程师检查服务器端日志。
invalid_client错误 我在新创建的LinkedIn开发者应用进行OAuth 2.0令牌交换时,持续遇到invalid_client错误。之前的应用也出现相同问题,因此我重新创建了应用。
配置信息
- LinkedIn开发者应用为今日创建(应用ID
[YOUR_FRESH_APP_ID]) - 标准应用,无需Marketing Developer Platform审批(
w_member_social权限无需该审批) - 已添加产品(均显示“已添加”状态,无待处理项):
- Sign In with LinkedIn using OpenID Connect
- Share on LinkedIn
- 请求的权限范围:
openid profile email w_member_social - 应用中注册的授权重定向URL:
https://www.fashionweekblueprint.com/api/social/oauth/linkedin/callback
正常工作的环节
授权步骤成功:用户进入LinkedIn授权界面,完成授权后,LinkedIn将用户重定向回我的回调地址并携带有效的code参数。
失败的环节
服务器端向https://www.linkedin.com/oauth/v2/accessToken发送POST请求进行令牌交换时,返回:
HTTP 401
Content-Type: application/json{"error":"invalid_client","error_description":"Client authentication failed"}
发送的请求格式
POST https://www.linkedin.com/oauth/v2/accessToken Content-Type: application/x-www-form-urlencoded grant_type=authorization_code &code=<code from authorize step> &redirect_uri=https%3A%2F%2Fwww.fashionweekblueprint.com%2Fapi%2Fsocial%2Foauth%2Flinkedin%2Fcallback &client_id=<client_id> &client_secret=<client_secret>
该格式与官方文档记录的格式一致。
已验证的内容
- 服务器环境中的Client ID与LinkedIn开发者平台显示的Client ID完全一致(字节级匹配,包括长度和字符集)
- Client Secret为刚在平台中重新生成的值,并直接复制到服务器环境;无空格,无截断
- 应用中仅存在一个活跃的Client Secret(无过期的次要密钥)
- 令牌交换中的
redirect_uri值与应用中注册的URI完全匹配 - 我实现了一个服务器端诊断端点,用于检查
process.env.LINKEDIN_CLIENT_ID和process.env.LINKEDIN_CLIENT_SECRET的格式(长度、前4个字符、后4个字符、空格标记),确认两者均与LinkedIn平台显示内容匹配 - 请求体为URL编码表单(非多部分表单,非JSON)
- 我使用Next.js 16服务器端fetch,通过
URLSearchParams传递请求体,并设置Content-Type: application/x-www-form-urlencoded - 之前的应用存在相同问题,删除后创建新应用仍出现相同错误
尚未尝试的操作
尚未尝试通过HTTP Basic Auth(Authorization请求头)发送client_id和client_secret,替代请求体参数。LinkedIn文档表明使用请求体参数是正确的,但部分OAuth实现要求使用Basic Auth。
问题
- 是否存在已知案例:即使Client ID和Secret值与开发者平台显示内容完全一致,仍返回
invalid_client错误? - LinkedIn是否要求在令牌端点通过HTTP Basic Auth传递客户端凭证,尽管文档显示使用请求体参数?
- 开发者平台凭证创建与LinkedIn认证后端识别凭证之间是否存在已知的传播延迟?
- “Sign In with LinkedIn using OpenID Connect”产品是否需要除“已添加”状态之外的额外配置?
欢迎LinkedIn工程师或已解决此问题的社区成员提供指导。
内容的提问来源于stack exchange,提问作者Thomas McClure

