Ruby on Rails集成Xero API获取Token Set时遇invalid_client错误求助
Xero API集成Ruby on Rails时
get_token_set_from_callback返回invalid_client错误排查 错误现象
调用get_token_set_from_callback获取Token Set时触发XeroRuby::ApiError,HTTP状态码400,响应体为{"error":"invalid_client"},完整错误详情:
*** XeroRuby::ApiError Exception: Error message: the server returns an error HTTP status code: 400 Response headers: {"content-type"=>"application/json; charset=UTF-8", "server"=>"nginx", "xero-origin-id"=>"IdentityServer.Web", "xero-causation-id"=>"63c9c7b03d7f435aa5dd801d96e8c152", "xero-message-id"=>"9e6951801da040ac94f61ab3392e3feb", "xero-activity-id"=>"adbfa8002310478c9d223f71e47b5b17", "xero-correlation-id"=>"6069553f3b9843f992e54f59f7bde8c0", "content-length"=>"26", "expires"=>"Wed, 01 Feb 2023 12:40:41 GMT", "cache-control"=>"max-age=0, no-cache, no-store", "pragma"=>"no-cache", "date"=>"Wed, 01 Feb 2023 12:40:41 GMT", "connection"=>"close", "set-cookie"=>"Device=961bc311701f4e20a0a2a7c0b6900dad; expires=Tue, 01 Feb 2028 12:40:41 GMT; path=/; samesite=none; httponly, _abck=CF3C26F9436304BF37101493FFAD83AF~-1~YAAQscNQaDKxnNKFAQAAPFz+DAnlKYqiZGnjCEbMvoyet1jSR8zH92SopvoLwB4qij7m04HY3vz38HatmtYuYAgN43HShtEj4miB94A9kiGQvrTNgMw9fNcpXV5sZ7JVNARjYdFjRYo0hU/n+qpWeEFH5OgBb8gzYVcOP5KqhPLgOd2ctiJrhmWiEmaeNZVbKj/spi60wt24oTv4jeWSplHq+i1LIzvPWLsVSU8RGKddmx+w7QnmtuWgbogouQljdvXS2Hrp9jDQsQXbvC9cWLy7A4AINQy7DLKP53mRgbqhdl7rG4Zyy8Bkv8nuxJvboM1MmdmorDngUVMNKkxpfdrWfJB5dv1Dbs3BOxJS2s9lRN56ugyI~-1~-1~-1; Domain=.xero.com; Path=/; Expires=Thu, 01 Feb 2024 12:40:41 GMT; Max-Age=31536000; Secure, bm_sz=D5B91089FE0B5C15AAF78A78C3DC4631~YAAQscNQaDOxnNKFAQAAPFz+DBKO2MjN+su/jV34lpo0F8Da/HIe1gG6gWfP7mzR6F7LwAPpRmm2lbXSjxw8/92CaTTcdsebzypKwiiowvOYOOI5/2TdwwcrU2bLSe9jN9YgUIS5izdAcysuz8S4pjx5OnNVe1HvhmUOeX8P/njVXeF7sQbFwmoAz3HyAO2AbJK0FGybHT8Spbfujl91GJ8+8YUf8voUQObj8r7o3K3GbWCycMG0lp6yupNoF7qfkPEuIl2vzMNCF0m2ZLH9a+akzpzc14KqjSwuz3k+++NK~3551286~3225656; Domain=.xero.com; Path=/; Expires=Wed, 01 Feb 2023 16:40:41 GMT; Max-Age=14400"} Response body: {"error":"invalid_client"}
相关代码
Token获取调用代码
@token_set = @xero_client.get_token_set_from_callback(params[:code])
HomeController代码
class HomeController < ApplicationController def index require 'xero-ruby' require 'httparty' creds = { client_id: '...', client_secret: '...', redirect_uri: 'http://localhost:3000/login', scopes: 'accounting.attachments', state: "Optional value to pass through auth flow" } config = { timeout: 30, debugging: true } @xero_client ||= XeroRuby::ApiClient.new(credentials: creds, config: config) @authorization_url = @xero_client.authorization_url end end
LoginController代码
class LoginController < ApplicationController def index require 'xero-ruby' creds = { client_id: '...', client_secret: '...', redirect_uri: 'http://localhost:3000/login', scopes: 'accounting.attachments', state: "Optional value to pass through auth flow" } config = { timeout: 30, debugging: true } @xero_client ||= XeroRuby::ApiClient.new(credentials: creds, config: config) byebug @token_set = @xero_client.get_token_set_from_callback(params[:code]) end end
排查原因
invalid_client错误本质是Xero身份服务无法识别你的客户端凭证,常见原因包括:
- Client ID或Client Secret填写错误,存在多余空格、换行或大小写差异
- 代码中的
redirect_uri与Xero开发者后台配置的地址不完全匹配(包括协议、端口、路径) - 客户端实例重复初始化导致配置不一致
- 敏感凭证硬编码时出现复制错误
解决方案
核对客户端凭证
登录Xero开发者门户,进入应用详情页面,复制精确的Client ID和Client Secret,替换代码中的占位符,确保无多余字符。验证Redirect URI匹配
在Xero应用的「Authentication」设置页,检查「Redirect URIs」列表是否包含http://localhost:3000/login,必须完全一致(协议、端口、路径均不能有差异),若缺失则添加该地址。统一客户端实例配置
避免在多个控制器中重复初始化Xero客户端,可将配置抽成初始化器:
创建config/initializers/xero.rb:require 'xero-ruby' XERO_CREDENTIALS = { client_id: ENV['XERO_CLIENT_ID'], client_secret: ENV['XERO_CLIENT_SECRET'], redirect_uri: 'http://localhost:3000/login', scopes: 'accounting.attachments' } XERO_CONFIG = { timeout: 30, debugging: true } def xero_client @xero_client ||= XeroRuby::ApiClient.new(credentials: XERO_CREDENTIALS, config: XERO_CONFIG) end之后在控制器中直接调用
xero_client即可,减少配置不一致风险。使用环境变量存储敏感信息
不要将Client ID和Secret硬编码在代码中,使用dotenvgem管理环境变量,创建.env文件:XERO_CLIENT_ID=你的ClientID XERO_CLIENT_SECRET=你的ClientSecret确保
.env文件被添加到.gitignore中,避免凭证泄露。
内容的提问来源于stack exchange,提问作者Jack Dawson
相关产品推荐
相关产品推荐

