Sign in With Google之服务端验证 您所在的位置:网站首页 谷歌密码格式不对 Sign in With Google之服务端验证

Sign in With Google之服务端验证

2024-05-19 15:23| 来源: 网络整理| 查看: 265

前言

关于使用Google第三方登录服务端如何进行登录验证。Google登录流程中,服务器的主要工作为验证用户信息以确保此次登录为有效登录,然后让当前登录的用户进行应用服务器的相应流程。另一方面,用户在授权登录后,应用服务器可以通过用户的授权获取到access_token,以便后续访问Google的其他API。

登录流程

根据上面的图所示:

在用户点击"Sign in With Google"的按钮后,客户端将会收到一个来自OAuth服务器并且只能使用一次的code,客户端将该code发送至应用服务器,这里由客户端处理。

应用服务器用该code向Google API服务器请求access_token和refresh_token,这里需要注意:

a. 每个code只能使用一次 b. 只要code有效,那么每次请求Google都将返回access_token c. 在获取到refresh_token之后,需要将其保存起来用于后续刷新access_token使用(access_token存在过期时间),因为在后续的refresh_token交换请求将返回空

请求access_token和refresh_token的API为https://oauth2.googleapis.com/token 请求参数有:

参数名 解释 code 用户授权后客户端获取到的code client_id 应用ID client_secret 应用密钥 redirect_uri 在 API控制台页面 配置的授权重定向URI grant_type 固定值:authorization_code

Google返回的参数有:

参数名 解释 access_token 用于访问Google API的token expires_in access_token有效期, 单位: 秒 id_token Google数字签名了的用户身份信息 scope access_token授予的访问范围,以空格分隔的、区分大小写的字符串列表表示。 token_type token类型,这里总是返回Bearer refresh_token 用于刷新access_token的token

下面以golang为例, 发送请求:

var ( clientId = "your clientId" clientSecret = "your clientSecret" code = "your code" redirectUri = "your redirectUri" url = "https://oauth2.googleapis.com/token" ) reader := strings.NewReader(fmt.Sprintf("client_id=%s&client_secret=%s&redirect_uri=%s&grant_type=authorization_code&code=%s", clientId, clientSecret, redirectUri, code)) response, err := http.Post(url, "application/x-www-form-urlencoded", reader) handleResponse(response) handleErr(err)

刷新access_token的API为: https://oauth2.googleapis.com/token

请求参数有:

参数名 解释 client_id 应用ID client_secret 应用密钥 refresh_token access_token值 grant_type 固定值:refresh_token

返回的参数有:

参数名 解释 access_token 用于访问Google API的token expires_in access_token有效期 token_type token类型,这里总是返回Bearer scope access_token授予的访问范围,以空格分隔的、区分大小写的字符串列表表示。 服务器获取到access_token和refresh_token之后便可以开始验证用户信息(idToken)是否有效。 如何验证用户身份信息

用户的身份信息是包含在idToken中的,idToken为 JWT 格式。按照 Google官网 介绍,idToken需要验证的内容有:

使用Google公钥确认idToken被正确的签名 aud的值应该与你应用的client_id相同 iss的值为accounts.google.com或者https://accounts.google.com 有效期尚未过

官网建议的验证方式有两种:

使用Google的验证库,包括Java, Node.js, PHP, Python, 当然, Go语言的库为: Golang, 如果使用Go语言的库,需要注意如果你的项目中引入了etcd,那么你需要注意关于etcd GRPC版本所引起的一个老生常谈的问题了,我在使用过程中解决办法是降低了Golang的版本,对应go.mod中为: replace ( google.golang.org/grpc => google.golang.org/grpc v1.26.0 google.golang.org/api => google.golang.org/api v0.14.0 )

关于验证idToken的代码为:

import ( "http" "github.com/dghubble/oauth1" "google.golang.org/api/option" "google.golang.org/api/oauth2/v2" ) oatuService, err := oauth2.NewService(context.Background(), option.WithHTTPClient(http.DefaultClient)) if err != nil { log4go.Errorf("%v\n", err) return nil, err } tokenInfoCall := oatuService.Tokeninfo() tokenInfoCall.IdToken(googleToken) tokenInfo, err := tokenInfoCall.Do() //根据tokenInfo中的字段进行验证

注意:Google建议生产环境使用此方法进行验证

调用Google的API进行验证, 验证API为: https://oauth2.googleapis.com/tokeninfo?id_token={idToken}, 如:

https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123

请求方法既可以是POST也可以是GET, 需要注意的是, 在收到API回复后只有当StatusCode为http.StatusOK时才能进行下一步校验。

idToken校验API返回的结果为JSON键值对,如:

{ // 这6个字段是所有idToken都包含的 "iss": "https://accounts.google.com", //token签发者,值为https://accounts.google.com或者accounts.google.com "sub": "110169484474386276334", //用户在该Google应用中的唯一标识,类似于微信的OpenID "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com", //具体我也不知道,猜测与aud相同,都是应用的client_id "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com", //client_id "iat": "1433978353", //签发时间 "exp": "1433981953", //过期时间 // 下面的字段只有当用户授权了"profile"和"email"权限后才会出现 "email": "[email protected]", //用户邮箱 "email_verified": "true", //邮箱是否已验证 "name" : "Test User", //用户名 "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg", //用户头像 "given_name": "Test", //名 "family_name": "User", //姓 "locale": "en" //所属地区 }

注意: 因为在授权过程中和获取access_token的过程中都会获取到idToken,所以服务器验证的idToken既可以由客户端传给服务器,也可以是服务器自己获取。但是在登录过程中,客户端获取到的授权code必须传给服务器

参考资料

Google Sign-In for server-side apps Authenticate with a backend server Using OAuth 2.0 to Access Google APIs

原文链接

Sign in With Google之服务端验证



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有