【冷门教程】接入谷歌OAuth2.0登录的分析和代码实践
本文需结合系列文章第一篇《谷歌OAuth2.0开发的正确配置步骤 》食用。
背景
最近开始摸索出海产品的方案,于是就想在现有产品上做试验,我现有的服务结构是这样的:
一个公共服务器负责公共模块,不同产品有自己的业务服务器和客户端。搭个公共服务器的主要好处有两点,第一是通用功能可以一次开发,重复利用,(如:第三方登录、内容安全审核);第二是可以方便共享数据(如:IP黑名单)。
说回开发出海产品,登录功能是第一要务,我的网站原本已支持微信和github的oauth2.0登录,心想公共服务圈再加个谷歌登录岂不是轻而易举?
然而问题出现了,我的服务器是腾讯云的国内服务器,根本无法访问谷歌的API。经过一番尝试后,我发现腾讯云国内服务器可以调用腾讯云国外节点的serverless应用。
那么本次做试验的技术组合就确定了:现有产品的业务服务器 + 腾讯云serverless + 谷歌API。
根据预研技术的习惯,要自下而上推进,那么就要先研究清楚谷歌API的请求流程。
谷歌OAuth2.0
该说不说,谷歌API文档写得真烂,花了一天多,在谷歌API文档、搜索引擎、stackoverflow多方检索下才找齐正确的文档。
在开始调用API之前,请先查看后台配置:谷歌OAuth2.0开发的正确配置步骤
现在,让我们顺着网线OAuth2.0的思路一步步扒开谷歌授权登录的真面目。
第一步,获取授权URL
根据谷歌 Google Web 授权文档,可知获取授权URL的请求是这样:
拼接出来的请求地址:
https://accounts.google.com/o/oauth2/v2/auth?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=YOUR_SCOPE&response_type=code
进入授权界面
在浏览器打开,能看到这个界面(这个就叫同意屏幕)就说明URL正确
如果缺少必填参数,或者参数有误,同意屏幕会显示错误code, 到文档页 查一下是什么原因,然后改正就好了。
授权登录后,会重定向到你的回调地址,如:
换取token
根据文档可知,换取token的请求如下:
我们在postman试一下,
为什么报错了?根据提示描述分析,应该是code有问题。
我的code是从重定向回来的地址上复制的,不可能有错误。
定睛一看,code里有个%2F,这不是斜杠吗?改成斜杠试试
果然成功了,这里实际返回字段和谷歌文档里写的并不一样,这里的id_token
是用户信息加密后的密文,所以只要解密id_token就能获得用户信息,执行登录逻辑了。
node中解密id_token
使用jwt-decode
我截图出来code都不打码,我不怕被人盗用吗?我们在postman再次提交请求看看
失败了,因为code仅一次有效。
到这里我们已经把谷歌登录流程梳理清楚了,你完全可以根据自己的开发习惯去完成自己的服务端代码。但是,如果你想继续学习serverless应用开发部署,甚至想复制点代码,那请继续阅读。
创建腾讯serverless应用
使用云函数或者serverless本身就是追求短平快,所以这里serverless应用的开发也就要求简单高效,而不是完善的应用配置等。
首先,你得找到腾讯serverless的入口:腾讯云 Serverless
开始创建应用
要短平快,当然选择Koa模板
根据页面提示填一下基本信息,区域一定要选择非内地地区,完成后就会看到你创建的serverless应用的信息
点“开发部署”,最快的做法就是下载项目模板,然后修改,所以我下载了
然后打开下载的项目,准备开发
加点基础代码
敲代码也是个千人千面的活,模板当然够用了,但是为了更省事,我们还得加点自己的代码,提升一下开发体验。
修改代码前,我们先看一下模板的目录结构
自动注册路由
这个serverless会有多个接口,所以我们写一个自动注册路由。
在根目录创建routes文件夹,放一个test.js,这个文件测试完后可以删掉
app.js写一个自动注册路由的方法
node app.js
启动服务,可以看到确实自动注册了
添加环境变量配置
先安装依赖:
依次创建三个配置文件:
Koa环境变量优先级是先找当前环境的配置文件,如果没有就到.env里继续找,所以开发环境和生产环境一样的配置写在.env文件里统一维护就可以了
三个文件需要写入的配置如下:
app.js里添加环境变量判断
package.json里修改启动命令
现在执行不同启动命令,把process.env.NODE_ENV
打印出来就可以看到区别了。
热更新
没有热更新的服务开发是没有灵魂的,按步骤来:
安装nodemon
修改启动命令:
使用 npm run dev
启动,再修改一下test.js的代码(随便改什么,不影响功能就可以),然后保存,我们会看到控制台打印了新的信息了,那就是可以热更新了。
开始开发
基础代码都完善了,现在可以无干扰开发业务接口了
首先,在routes
下创建一个新文件,就叫做googleAuth.js
吧。
根据第二节的思路,我们可以确定需要有两个接口:
1、获取授权页面地址
2、获取id_token
先写下框架,锁定开发的焦点
安装依赖
依赖说明:
googleapis
是谷歌API的Node依赖
jwt-decode
是用来解码token获取用户信息
nanoid
用来生成临时state,防止攻击
注意看nanoid的版本,最新版不支持commonJS,这也是一个坑,要去看nonaid更新记录才知道哪个版本以下支持commonJS。
现在我们施展一下魔法,获得完整代码,让我们通过代码注释来讲解
这样本文要开发的代码都完成了,当你有一个这样的公共服务器时,业务服务器还需要做哪些工作?
对于googleOauth2Url
接口,业务服务器只要做个转发就可以。
对于googleOAuth2Login
接口,业务服务器要做state有效期判断、用户数据入库、用户token生成和缓存等等业务系统自己的逻辑。
将来,如果我还有其它业务系统要接入公共服务,只需要优化一下环境配置就可以了,这是真正的一次开发,永久使用。
如果你觉得这些代码还有点用,可以到Github自取(有star就更好了):👉google-login-tencent-serverless
上传代码,更新环境变量,部署验证
再次打开serverless后台,部署代码
超时时间我选择了30秒,是个比较长的时间限制,主要是担心访问国外服务比较慢。
部署完成后,就能看到一个URL,这就是你生产环境的服务地址
结语
以上就是实现谷歌OAuth2.0的全部内容了,写这篇文章的目的是抹平谷歌OAuth2.0开发的信息差,跟着以上步骤思路实现,你只需要半个小时就能完成自己的谷歌授权登录功能。