Twitter登陆报错: Desktop applications only support the oauth_callback

本文针对Twitter登录功能出现的故障进行了详细的原因分析,并提供了具体的解决办法,包括如何设置正确的CallbackUrl和确保APIKEY与APISecret的正确配置。

Twitter登陆功能时遇到故障:

Desktop applications only support the oauth_callback value

E/Twitter: Failed to get request token com.twitter.sdk.android.core.TwitterApiException: HTTP request failed, Status: 400

E/Twitter: Authorization completed with an error com.twitter.sdk.android.core.TwitterAuthException: Failed to get request token

转载请注明链接:http://blog.youkuaiyun.com/feather_wch/article/details/79612471

原因分析

可能1: 没有在Twitter自己的应用中设置Callback Url,这是用于登陆成功后的回调的,没有的话设置个合法的URL即可,我设置为https://www.baidu.com/

可能2:没有正确设置API KEY和API Secret
解决办法:Twitter集成教程中第1-2的第三点:需要设置Callback Url

解决

  1. 登陆https://apps.twitter.com
  2. 进入自己的APP并进入setting选项。
  3. 设置Callback Url
你提供的这段 Java 代码实现了一个 OAuth 授权流程中的部分逻辑,包括: 1. 获取用户传入的 `oauth_callback` 和 `oauth_consumer_key` 2. 对 `oauth_callback` 进行 URL 编码 3. 如果没有提供 `oauth_token`,则获取临时 token,并跳转到授权页面 4. 如果有 `oauth_token`,则继续获取永久 token 并完成登录认证 整体逻辑是清晰的,但有一些潜在问题和改进建议。我们来**逐行分析、指出问题、并给出优化建议**。 --- ## ✅ 一、变量定义与参数获取 ```java String oauth_callback = this.getPara("oauth_callback", "", "回调地址"); String oauthConsumerKey = this.getPara("oauth_consumer_key", "", "公钥"); ``` - ✅ **优点:** 使用了封装好的 `getPara()` 方法,语义清晰。 - ⚠️ **建议:** 确保 `getPara()` 方法对输入参数进行了安全处理(如 XSS 过滤),尤其是 `oauth_callback`,防止开放重定向漏洞。 --- ## ✅ 二、URL 编码处理 ```java if (StringUtils.isNotBlank(oauth_callback)) { oauth_callback = getURLEncoderString(oauth_callback); } ``` - ❓ **疑问:** `getURLEncoderString()` 是你自己实现的方法吗?如果是,请确保它使用的是 `StandardCharsets.UTF_8`,并且正确地对整个 URL 做了编码。 - ⚠️ **风险:** 如果这个方法内部已经做了 URL 编码,而你在后面又使用了 `UriComponentsBuilder.queryParam(...)`,就可能导致**双重编码**。 ### ✅ 建议: 你可以直接删除手动编码这一层,交给 `UriComponentsBuilder` 来统一处理: ```java // 删除下面这段 // if (StringUtils.isNotBlank(oauth_callback)) { // oauth_callback = getURLEncoderString(oauth_callback); // } ``` --- ## ✅ 三、构建跳转 URL ```java String redirectUrl = UriComponentsBuilder.fromHttpUrl(authUrl) .queryParam("oauth_callback", oauth_callback) .queryParam("oauth_token", tempToken) .build(false) .toUriString(); ``` - 🧨 **严重问题:** 你使用了 `.build(false)`,这意味着不会自动进行 URL 编码! - ⚠️ **后果:** 如果 `oauth_callback` 没有被提前正确编码(或未被编码),最终生成的 URL 可能包含非法字符,导致请求失败或安全问题。 ### ✅ 正确写法: ```java String redirectUrl = UriComponentsBuilder.fromHttpUrl(authUrl) .queryParam("oauth_callback", oauth_callback) // 应该是原始字符串 .queryParam("oauth_token", tempToken) .build() // 不加 false,让 Spring 自动编码 .toUriString(); ``` > ✅ 如果你确定 `oauth_callback` 已经编码过,那么 `.build(false)` 才适用;否则应使用 `.build()`。 --- ## ✅ 四、异常处理与日志记录 ```java try { response.sendRedirect(redirectUrl); } catch (IOException e) { log.error("重定向失败,redirect error:{}", e.getMessage(), e); throw new BaseException("用户登录授权认证失败"); } ``` - ✅ **优点:** 异常捕获完整,日志记录详细。 - ✅ **建议:** 可以在抛出异常前将 `redirectUrl` 也记录下来,方便排查问题。 --- ## ✅ 五、获取永久 Token 与用户信息 ```java String permanentToken = getPermanentToken(tempToken, oauthConsumerKey); String ygdm = getUser(permanentToken, oauthConsumerKey); return getSsoDataByYgdm(request, response, ygdm); ``` - ✅ **优点:** 流程合理,逐步推进认证过程。 - ⚠️ **建议:** - 确保 `getPermanentToken()` 和 `getUser()` 的网络请求有超时机制和异常处理。 - 添加日志输出,便于追踪流程。 --- ## ✅ 六、总结问题点与改进建议 | 问题 | 描述 | 建议 | |------|------|------| | 双重编码风险 | 手动编码后再用 `build(false)` 可能导致错误 | 移除手动编码,或使用 `build()` | | 编码方式不确定 | `getURLEncoderString()` 实现不透明 | 建议使用标准库 `URLEncoder.encode(str, StandardCharsets.UTF_8)` | | 构建 URL 方式不当 | 使用 `.build(false)` 导致未编码 | 改为 `.build()` | | 日志信息不全 | 未打印关键参数 `redirectUrl` | 在日志中加入 `redirectUrl` | --- ## ✅ 优化后的完整代码示例 ```java String oauth_callback = this.getPara("oauth_callback", "", "回调地址"); String oauthConsumerKey = this.getPara("oauth_consumer_key", "", "公钥"); log.info("原始 oauth_callback: {}", oauth_callback); String tempToken; String oauthToken = Convert.toStr(para.get("oauth_token")); if (StringUtils.isBlank(oauthToken)) { // 获取临时token tempToken = getTempToken(oauth_callback, oauthConsumerKey); // 用户登录授权认证 String authUrl = "http://172.25.1.71:8090/platform/oauth/authorize"; String redirectUrl = UriComponentsBuilder.fromHttpUrl(authUrl) .queryParam("oauth_callback", oauth_callback) // 原始字符串,由 builder 自动编码 .queryParam("oauth_token", tempToken) .build() .toUriString(); log.info("跳转 URL: {}", redirectUrl); try { response.sendRedirect(redirectUrl); } catch (IOException e) { log.error("重定向失败, redirectUrl: {}, error: {}", redirectUrl, e.getMessage(), e); throw new BaseException("用户登录授权认证失败"); } return null; } tempToken = oauthToken; log.info("临时 oauth_token: {}", tempToken); // 获取永久token String permanentToken = getPermanentToken(tempToken, oauthConsumerKey); // 获取员工内码 String ygdm = getUser(permanentToken, oauthConsumerKey); return getSsoDataByYgdm(request, response, ygdm); ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值