最近完成了博客的评论系统,第三方登录使用了 GitHub OAuth App。至于教程或者示例,随便谷歌、百度一下都是一大片,或许正是因为查的太多了,以至于所有的教程都在告诉你怎么注册、怎么调用 API、怎么用 XXX 后端获取数据等等等等…
但是他们好像都忽略了一个问题:
—— 在获取 Token 或者用户信息之后,客户端要怎么跳转回用户授权之前的页面?
先声明一下,这篇文章不会教你怎么注册或使用 GitHub OAuth App,如果你还不熟悉它,可以先阅读一下官方文档,如果你不太喜欢英语,可以看看阮一峰的GitHub OAuth 第三方登录示例教程或者其他大佬 / 论坛的教程。
好了,先看一下 GitHub OAuth 的流程:
- 浏览器带
client_id
和redirect_uri
跳转到 GitHub - 用户授权
- 如果用户同意授权,GitHub 会返回一个
code
参数,形式为https://redirect_uri?code=xxxxxxxxxxxxx
- 客户端带
code
client_id
和client_secret
发送 POST 请求到 GitHub 获取token
- 客户端使用
token
获取用户信息
如果用 URL 的跳转来表现的话大概就是这样:
blog.com/post/01.html
---->
https://github.com/login/oauth/authorize?client_id=xxx&redirect_uri=xxx
---->
api.blog.com/?code=xxx # api.blog.com就是你填在GitHub OAuth App的Callback URL
----> POST
https://github.com/login/oauth/access_token
---->
???
对!问题来了!
怎么跳转?跳哪里?
作为开发者,我肯定是想跳回blog.com/post/01.html
实现无缝体验对吧…
然而就这个问题,不管是 CSDN,还是 Stack Overflow,甚至官方文档,
全都没有!
终于,在死了不知道多少脑细胞后,我想出了如下实现过程:
-
假设用户在
blog.com/post/01.html
这张页面上点击了 GitHub 登录按钮,这个登录按钮不要直接跳转到 GitHub 授权页面,先跳转到你自己设置的 GitHub OAuth App 的 Callback URL,这里假设是api.blog.com
,把当前页面的 URL 传给api.blog.com
,例如:api.blog.com?url=blog.com/post/01.html
-
这样在跳转到
api.blog.com
的时候,你就知道了点击登录的是哪张页面了,这时候可以把传过来 URL 记录到localStorage
或者 Cookie,甚至是后端的 Session,反正不管怎么样,找个地方记录一下就可以了,因为这时候我们还要跳转到github.com
,不记录的话就丢失了数据 -
用户在
github.com
完成授权后,还是会跳转到api.blog.com
,因为跳转前记录了授权前传来的页面 URL,在你获取到 Token 之后,你可以把 URL 再读取出来:// localStorage 这么用 window.localStorage.getItem('URL'); // Cookie 这么用 // 这个function w3c抄来的 function getCookie(cname) { var name = cname + "="; var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == ' ') { c = c.substring(1); } if (c.indexOf(name) == 0) { return c.substring(name.length, c.length); } } return ""; } getCookie('URL');
获取用户信息的请求可以在api.blog.com
做,也可以像我一样带着token
回到blog.com/post/01.html
去做。
因为自己的博客URL 特殊,又是 Hash 又是 URL Param(原本是单页 App,现在已调整为纯静态,但是不影响思路),而且也不想用户在回到页面的时候,URL 后面跟着一个长长的token
,我还新加了一个跳转页面 blog.com/r.html
,这个页面负责接收token
和跳转的页面,将token
写入浏览器存储(上面说的localStorage
或者 Cookie)之后再进行跳转,在blog.com/post/01.html
完成用户信息的调用后删除记录在浏览器存储里面的token
。
虽然流程跑通了,但是我还是很好奇为什么 GitHub 官方文档里完全找不到这一部分的说明,在搜索引擎上也找不到相关文章…
随便吧,现在看起来,只能这样解决…