Xero API断开连接后重连不显示登录及组织选择页问题咨询
问题解答
现有方案合理性说明
- 删除浏览器XeroIdentity cookie的方案可以实现需求,但不是最优方案:该方案属于客户端强制清除登录态的操作,会同时清除用户在浏览器内的Xero官方平台登录状态,若用户同时打开了Xero网页端操作业务,会被强制登出,影响用户体验。
问题根本原因
你在服务端执行的撤销token、删除关联组织操作,仅解除了你的应用和Xero账号的授权绑定,并未清除用户浏览器侧Xero的单点登录(SSO)状态。因此用户重新发起授权时,Xero会识别到当前浏览器已登录的账号,直接跳过登录、组织选择步骤完成授权重定向。
最优替代方案
无需修改现有断开连接逻辑,只需要在你跳转到Xero OAuth2授权页的请求中,添加prompt参数即可实现需求:
- 仅需要展示组织选择页:添加
prompt=select_tenant参数,Xero会跳过登录验证,直接展示当前登录账号下的所有组织供用户选择 - 需要同时支持重新登录+选择组织:添加
prompt=login select_tenant参数,Xero会先强制展示登录页,登录完成后再展示组织选择页
现有断开代码的潜在问题修复
你当前的token撤销请求参数格式错误,可能导致token撤销实际未生效,需要调整:
原代码中撤销请求的Content-Type指定为application/x-www-form-urlencoded,但你传入的参数类型为application/json,不符合接口要求,修正后代码片段如下:
public async Task<JsonResult> RemoveConnection(string token, string Id) { try { if (Id == null) { return Json("Please connect with Xero first"); } else { var accessToken1 = ""; var tenantId1 = ""; var token1 = await _tokenStore.GetAccessTokenAsync(Id); accessToken1 = token1.AccessToken; var restclient1 = new RestClient("https://identity.xero.com/connect/revocation"); var request1 = new RestRequest(Method.POST); string encoded = base64encode(Configuration["xero:clientid"] + ":" + Configuration["xero:clientsecret"]); request1.AddHeader("authorization", string.Format("basic {0}", encoded)); request1.AddHeader("content-type", "application/x-www-form-urlencoded"); // 仅修改该行参数的媒体类型即可 request1.AddParameter("application/x-www-form-urlencoded",string.Format("token={0}", accessToken1),ParameterType.RequestBody); var response1 = restclient1.Execute(request1); var connections1 = await _xeroClient.GetConnectionsAsync(token1); foreach (var connection in connections1) { accessToken1 = token1.AccessToken; tenantId1 = connection.id.ToString(); var restClient = new RestClient("https://api.xero.com/connections/" + tenantId1 + ""); var request = new RestRequest(Method.DELETE); request.AddHeader("Authorization", string.Format("Bearer {0}", accessToken1)); var response = restClient.Execute(request); var x = response.Content; var connections12 = await _xeroClient.GetConnectionsAsync(token1); } var details = new { Result = "Disconnected", Status = "Ok" }; return Json(details); } } catch (Exception ex) { return Json(ex.Message); } }
内容的提问来源于stack exchange,提问作者test duck
相关产品推荐
相关产品推荐

