使用flutter_web_auth_2实现Fitbit OAuth2.0认证时遭遇PlatformException(CANCELED)错误
flutter_web_auth_2实现Fitbit OAuth2.0认证时遭遇PlatformException(CANCELED)错误
我明白你现在遇到的麻烦了——明明Fitbit账户里已经显示应用获得了授权,结果回到App就弹出PlatformException(CANCELED, User canceled login, null, null),连授权码都拿不到,确实挺闹心的。结合你贴的代码和问题描述,我帮你梳理几个最可能的原因和对应的解决办法:
1. 重定向URI的全平台配置不匹配
这是这类问题最常见的原因,Fitbit对重定向URI的匹配要求非常严格,而且需要在App的原生配置里正确注册Scheme:
- Fitbit开发者后台检查:确保你在Fitbit开发者控制台里填写的
Redirect URI和代码里的myapp://callback完全一致,包括大小写、斜杠、Scheme前缀,不能有任何差异。 - Android端配置:打开
android/app/src/main/AndroidManifest.xml,给你的主Activity添加对应的,用来捕获 myapp://开头的链接:<activity android:name=".MainActivity"> <!-- 其他配置 --> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="myapp" /> </intent-filter> </activity> - iOS端配置:打开
ios/Runner/Info.plist,添加CFBundleURLTypes配置,注册myapp这个Scheme:<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>myapp</string> </array> </dict> </array>
2. PKCE流程的细节疏漏
你的PKCE实现逻辑大体是对的,但有几个细节需要确认:
- code_verifier长度:Fitbit要求code_verifier的长度必须在43-128字符之间,你生成的是64个随机字节转base64url,理论上长度符合要求,但可以查看日志里的
_codeVerifier值,确认它的长度在范围内。 - code_challenge格式:确保生成的code_challenge是不带填充的base64url编码(你的代码里用
replaceAll('=', '')是对的),同时不能包含+、/这类字符(base64UrlEncode已经帮你换成-和_了,还是可以检查日志里的codeChallenge值确认)。
3. flutter_web_auth_2的配置选项冲突
你当前用了preferEphemeral: true和useWebview: true,有些设备上可能会因为临时会话或WebView的限制导致重定向失败:
- 可以尝试把
preferEphemeral改成false,使用持久化的浏览器会话; - 或者把
useWebview改成false,调用系统默认浏览器完成授权流程,看是否能解决问题。
4. Fitbit应用权限范围不匹配
虽然你代码里请求了activity的scope,但要确认Fitbit开发者后台里的应用权限是否也勾选了Activity相关的权限项,否则即使用户在授权页面点击了允许,也可能会触发隐性的权限错误,导致重定向异常。
额外调试建议
你可以在Fitbit授权页面点击“允许”后,仔细观察重定向的URL是否真的是myapp://callback?code=xxx的格式:
- 如果没有跳转到这个链接,说明是Fitbit那边没有正确触发重定向,要检查开发者后台的URI配置;
- 如果确实跳转到了这个链接,但App没捕获到,那就是原生配置的问题,再仔细核对Android/iOS的Scheme注册。
内容来源于stack exchange
相关产品推荐
相关产品推荐

