近期在开发新的网站,为了简化注册登录流程,想着接入三方的一键登录,由于新站点主要面向海外用户,所以选择接入 Google 的登录按钮。谷歌登录不需要什么审核,也不需要提交任何资源,相对于其他三方登录简单了很多。
这里是 Google 登录的官方文档 https://developers.google.com/identity/sign-in/web/sign-in?hl=zh-cn
相关官方文档:https://developers.google.com/identity/gsi/web/guides/get-google-api-clientid?hl=zh-cn
https://console.developers.google.com/apis/dashboard
选择 “API和服务”-》新建项目
进入第二步新建的项目下,选择 “API和服务”-》“凭据”
点击创建凭据,选择 “OAuth 客户端 ID”
首次创建凭据时系统会提示“如需创建 OAuth 客户端 ID,您必须先在同意屏幕上设置产品名称”,根据提示进行操作,填写在要求用户登录时展示的相关信息。
“OAuth 同意屏幕”的详情配置,在这里,可以填写你的应用的名字、图标等信息。
保存后,会提示需要验证应用,如下
注:如果仅作测试使用,则可以直接忽略这个验证操作,直接进入下一步,否则的话,建议按照提示进行验证。
访问 “凭据” - “创建凭据” - “OAuth 客户端 ID”,选择“Web 应用”,然后按照提示填入内容
最重要的是“Authorized JavaScript origins 已获授权的 JavaScript 来源”这个字段,谷歌只会允许在这个列表内的域名使用指定的 ClientID。所以,这里填写你的网站域名(带协议)。回车添加,然后保存。
对于本地测试或开发,请同时添加 http://localhost 和 http://localhost:端口号 ,网页添加 <meta name="referrer" content="no-referrer-when-downgrade" />
保存信息后,会弹出密钥和ID
记录三个信息:Client ID、Client Secret 和回调地址,后面我们会用到。
“应用密钥”可保护你应用程序的安全,因此请确保其不会泄露!也不要与任何人共享你的“应用密钥”!!!
附:Google OAuth 2.0 官方测试工具 https://developers.google.com/oauthplayground/
请务必在用户可能登录的任何页面上加载客户端库。请使用以下代码段:
<script src="https://accounts.google.com/gsi/client" async></script>
官方提供了一键生成 Html 代码的在线工具:https://developers.google.com/identity/gsi/web/tools/configurator?hl=zh-cn
填写 ClientID 和回调地址,点击下一步
设置按钮样式,点击获取代码
将获取到的代码粘贴到你的登录按钮想要放置的位置
设置完以后,刷新页面应该可以看到登录按钮了
上边的代码只是将登录按钮放到页面上了,前端登陆后,Google 会发送 Post 请求到你设置的回调地址中,会有两个参数,credential 和 g_csrf_token,credential 参数可以通过 google 官方的库解析出用户信息,g_csrf_token 参数是为了防止 CSRF 攻击。
相关文档:https://developers.google.com/identity/gsi/web/guides/verify-google-id-token?hl=zh-cn%2F%3Fq%3Dauto_prompt%20false
回调请求时,会将 g_csrf_token 令牌同时放入 Cookie 和 post 正文,我们需要校验这两个参数内容是否一致
gCsrfToken := c.PostForm("g_csrf_token")
if gCsrfToken == "" {
c.HTML(200, "login.gohtml", gin.H{
"msg": "参数错误:No CSRF token in post body.",
"selected": "login",
})
return
}
CookiegCsrfToken, err := c.Request.Cookie("g_csrf_token")
if err != nil || CookiegCsrfToken.Value != gCsrfToken {
c.HTML(200, "login.gohtml", gin.H{
"msg": "参数错误:Failed to verify double submit cookie.",
"selected": "login",
})
return
}
在收到前端发送过来的 Token 后,首先需要校验此 Token 是否合法,然后后端解析此 Token,取得相关数据,查找相关的用户,创建自己的会话信息。
校验有以下几个步骤:
取用户数据
如果上面所有的条件都满足,那么,这是一个合法的 Token,可以完全地取相关的数据了。
创建自己的会话
如果这个 sub 对应的用户已经存在,则创建此用户的会话。如果不存在,则可以创建一个新的用户,关联此 sub。
解析 JWT Token 的库
谷歌官方提供了库来解析:idtoken:https://google.golang.org/api/idtoken
使用方式极其简单:
package main
import (
"google.golang.org/api/idtoken"
)
func main() {
credential := c.PostForm("credential")
data, err := idtoken.Validate(c, credential, clientID)
userInfo := data.Claims
gid := userInfo["sub"].(string)
username := userInfo["name"].(string)
email := userInfo["email"].(string)
avatar := userInfo["picture"].(string)
}
注意:代码会在内部获取谷歌的公钥,所以,请确保这段代码在你的服务器上是“可行的”。