UWP应用中如何从Facebook登录获取Access Token?
嘿,我刚好踩过UWP WebView做OAuth登录的坑,咱们一步步来解决这个问题:
问题根源分析
你遇到的两个核心问题其实是关联的:
- Token快速消失:你直接读取
page.Source.AbsoluteUri的时机不对——WebView的导航是异步的,等你拿到这个URI时,页面已经开始跳转到后续的不安全链接,带Token的回调URL已经被覆盖了。 - 跳转不安全页面:大概率是OAuth服务的回调地址配置成了HTTP协议,UWP WebView对HTTP跳转有默认限制,或者回调后服务自动重定向到了HTTP页面,把Token带丢了。
解决方案
方案1:用NavigationStarting事件提前拦截带Token的URL
这是最可靠的方式,因为这个事件会在WebView开始加载新页面之前触发,能稳稳抓住带Token的回调URL,还能直接阻止跳转到不安全页面:
// 先给你的WebView注册导航开始事件 myWebView.NavigationStarting += MyWebView_NavigationStarting; private void MyWebView_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args) { string currentUri = args.Uri.AbsoluteUri; // 检查URL里是否包含我们要的access_token if (currentUri.Contains("access_token")) { // 取消本次导航,直接终止跳转,避免走到不安全页面 args.Cancel = true; // 安全截取Token(处理Token在URL末尾的情况) int tokenStartPos = currentUri.IndexOf("access_token=") + 13; int tokenEndPos = currentUri.IndexOf("&", tokenStartPos); if (tokenEndPos == -1) { tokenEndPos = currentUri.Length; } string accessToken = currentUri.Substring(tokenStartPos, tokenEndPos - tokenStartPos); // 这里拿到Token后就可以做你需要的操作了,比如保存到本地、跳转应用内页面 Debug.WriteLine("成功获取Token:" + accessToken); } }
方案2:改用自定义协议回调(更安全)
如果你的OAuth服务支持,把回调地址改成自定义协议(比如yourapp://oauth-callback),完全避开HTTP/HTTPS跳转的问题:
- 打开UWP应用的
Package.appxmanifest,切换到「声明」选项卡 - 选择「协议」,点击「添加」,在「名称」里填你的协议名(比如
yourapp) - 把OAuth服务的回调地址设置为
yourapp://oauth-callback?access_token=xxx&expires_in=3600
之后同样用NavigationStarting事件拦截,解析逻辑和上面一致,而且这种方式不会触发任何不安全跳转的提示。
方案3:修复原代码的细节问题(备选)
如果暂时没法改事件或回调地址,先修复你原代码里的小问题:
- 原代码里用
&是HTML转义后的符号,但实际URL里是原始的&,直接用uri.IndexOf("&")就行 - 要加判断,避免
IndexOf返回-1时抛出异常:
string r3 = page.Source.AbsoluteUri; if (r3.Contains("access_token")) { int tokenStart = r3.IndexOf("access_token=") + 13; int tokenEnd = r3.IndexOf("&", tokenStart); string token = tokenEnd == -1 ? r3.Substring(tokenStart) : r3.Substring(tokenStart, tokenEnd - tokenStart); // 处理Token }
不过这个方案还是不如方案1可靠,因为页面跳转速度太快,大概率还是抓不到Token。
内容的提问来源于stack exchange,提问作者steven
相关产品推荐
相关产品推荐

