Google OAuth登录后如何使用access_token、id_token获取用户邮箱信息
实现方案:通过Google OAuth返回的token获取用户邮箱
你已经在授权Scope中配置了openid%20email权限,可通过以下两种方案获取用户邮箱:
方案1:直接解析id_token(无需额外发起网络请求)
谷歌返回的id_token为标准JWT格式,由.分割为三部分,中间的载荷段经Base64Url解码后直接包含email字段,是最高效的实现方式。
方案2:使用access_token调用用户信息接口
通过access_token向谷歌用户信息接口发起GET请求,返回结果中可直接读取邮箱字段,适合需要同时获取更多用户信息的场景。
完整实现代码
首先需引入Newtonsoft.Json处理JSON序列化,添加命名空间引用:
Imports Newtonsoft.Json Imports Newtonsoft.Json.Linq Imports System.Text Imports System.IO Imports System.Net
定义数据实体类与辅助方法:
' Token接口返回结果实体 Public Class TokenResponse Public Property access_token As String Public Property id_token As String Public Property expires_in As Integer Public Property token_type As String Public Property refresh_token As String End Class ' 用户信息接口返回结果实体 Public Class UserInfoResponse Public Property email As String Public Property verified_email As Boolean Public Property name As String Public Property picture As String End Class ' JWT专用Base64Url解码辅助方法 Public Function Base64UrlDecode(input As String) As Byte() input = input.Replace("-", "+").Replace("_", "/") Select Case input.Length Mod 4 Case 0 : Exit Select Case 2 : input &= "==" Case 3 : input &= "=" Case Else : Throw New Exception("非法的Base64Url格式字符串") End Select Return Convert.FromBase64String(input) End Function
修改你原有Page_Load中的逻辑(注意修正原有逻辑中参数判断的错误):
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load ' 修正原有逻辑错误:谷歌回调返回的授权码参数为code,不是id If Not String.IsNullOrEmpty(Request.QueryString("code")) Then Dim geturlCode As String = Request.QueryString("code") Dim WebRequest1 As HttpWebRequest = CType(WebRequest.Create(urlGetToken), HttpWebRequest) Dim Parameter As String = "code=" & geturlCode & "&client_id=" + clientID & "&client_secret=" + clientSecret & "&redirect_uri=" + redirecturi & "&grant_type=authorization_code" WebRequest1.Method = "POST" WebRequest1.ContentType = "application/x-www-form-urlencoded" Dim utfenc As UTF8Encoding = New UTF8Encoding() Dim bytes As Byte() = utfenc.GetBytes(Parameter) Dim os As Stream = Nothing Try WebRequest1.ContentLength = bytes.Length os = WebRequest1.GetRequestStream() os.Write(bytes, 0, bytes.Length) Catch End Try Dim WebResponse As HttpWebResponse = CType(WebRequest1.GetResponse(), HttpWebResponse) Dim responseStream As Stream = WebResponse.GetResponseStream() Dim responseStreamReader As StreamReader = New StreamReader(responseStream) Dim result = responseStreamReader.ReadToEnd() ' --------------- 以下为新增的获取邮箱逻辑 --------------- ' 反序列化token返回结果 Dim tokenRes As TokenResponse = JsonConvert.DeserializeObject(Of TokenResponse)(result) ' 方案1:解析id_token直接获取邮箱 Dim jwtParts = tokenRes.id_token.Split("."c) Dim payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(jwtParts(1))) Dim payloadObj = JObject.Parse(payloadJson) Dim userEmail As String = payloadObj("email").ToString() ' 若使用方案2请注释上面方案1的代码,启用下方代码 'Dim userInfoReq As HttpWebRequest = CType(WebRequest.Create("https://www.googleapis.com/oauth2/v3/userinfo"), HttpWebRequest) 'userInfoReq.Method = "GET" 'userInfoReq.Headers.Add("Authorization", "Bearer " & tokenRes.access_token) 'Dim userInfoResp As HttpWebResponse = CType(userInfoReq.GetResponse(), HttpWebResponse) 'Dim userInfoReader As New StreamReader(userInfoResp.GetResponseStream()) 'Dim userInfoJson As String = userInfoReader.ReadToEnd() 'Dim userInfoRes As UserInfoResponse = JsonConvert.DeserializeObject(Of UserInfoResponse)(userInfoJson) 'Dim userEmail As String = userInfoRes.email End If End Sub
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

