locked
Email is not present from some gmail account. (Open ID Connect) RRS feed

  • Question

  • User944339287 posted

    Hi guys.. the following is my code to implement google login. 

    Everything is working as expected but i found that email is not present from some gmail account.

    how come? it's because of setting issue (user set not to share his/her email)? how can i make sure email value is present in every attempt to make the google login working fine?

    https://developers.google.com/identity/protocols/OpenIDConnect#scope-param

           Dim clientid As String = "XXXXXXXXXXXXXXXXXXXXXXXXXXX"
           Dim clientsecret As String = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
           Dim redirection_url As String = "http://localhost:51016/access/googleLogin.aspx"
           Dim url As String = "https://accounts.google.com/o/oauth2/v2/auth?scope=profile&include_granted_scopes=true&redirect_uri=" & redirection_url & "&response_type=code&client_id=" & clientid & ""
           Response.Redirect(url)



    Thursday, March 12, 2020 2:18 AM

Answers

  • User-719153870 posted

    Hi kengkit,

    Sorry for the late reply and thanks for the code. Have you tried the suggestion i provided? I mean " you can set the scope value like "scope = openid profile email"".

    I created a demo based on your code and reproduced the issue(can not get email information), then changed the scope parameter as i said and the demo works and we can get email information now.

    Below is the demo, maybe you want to refer:

    LoginPage.aspx:

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
                <asp:LinkButton ID="googleLogin" runat="server" OnClick="googleLogin_Click">googleLogin</asp:LinkButton>
            </div>
        </form>
    </body>
    </html>

    LoginPage.aspx.vb:

    Public Class LoginPage
        Inherits System.Web.UI.Page
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
        End Sub
    
        Protected Sub googleLogin_Click(sender As Object, e As EventArgs)
            Dim clientid As String = "**********-*****************************.apps.googleusercontent.com"
            Dim clientsecret As String = "*********************"
            Dim redirection_url As String = "https://localhost:44325/googleLogin.aspx"
            Dim url As String = "https://accounts.google.com/o/oauth2/v2/auth?scope=openid profile email&include_granted_scopes=true&redirect_uri=" & redirection_url & "&response_type=code&client_id=" & clientid & ""
            Response.Redirect(url)
        End Sub
    
    End Class

    googleLogin.aspx.vb:

    Imports System.IO
    Imports System.Net
    Imports System.Web.Script.Serialization
    Public Class googleLogin
        Inherits System.Web.UI.Page
    
        Private clientid As String = "*************-**************************.apps.googleusercontent.com"
        Private clientsecret As String = "*************************"
        Private redirection_url As String = "https://localhost:44325/googleLogin.aspx"
        Private url As String = "https://accounts.google.com/o/oauth2/token"
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            If Page.IsPostBack = False Then
                If Request.QueryString("code") IsNot Nothing Then
                    GetToken(Request.QueryString("code").ToString())
                Else
                    Response.Redirect("/*****.aspx")
                End If
            End If
        End Sub
    
        Public Class Tokenclass
            Public Property access_token As String
            Public Property token_type As String
            Public Property expires_in As Integer
            Public Property refresh_token As String
        End Class
    
        Public Class Userclass
            Public Property id As String
            Public Property name As String
            Public Property given_name As String
            Public Property family_name As String
            Public Property gender As String
            Public Property email As String
            Public Property picture As String
        End Class
    
        Public Sub GetToken(ByVal code As String)
    
            Dim poststring As String = "grant_type=authorization_code&code=" & code & "&client_id=" & clientid & "&client_secret=" & clientsecret & "&redirect_uri=" & redirection_url & ""
            Dim request = CType(WebRequest.Create(url), HttpWebRequest)
            request.ContentType = "application/x-www-form-urlencoded"
            request.Method = "POST"
            Dim utfenc As UTF8Encoding = New UTF8Encoding()
            Dim bytes As Byte() = utfenc.GetBytes(poststring)
            Dim outputstream As Stream = Nothing
    
            Try
                request.ContentLength = bytes.Length
                outputstream = request.GetRequestStream()
                outputstream.Write(bytes, 0, bytes.Length)
            Catch ex As Exception
                Page.Response.Write(ex.Message)
            End Try
    
            Dim response = CType(request.GetResponse(), HttpWebResponse)
            Dim streamReader = New StreamReader(response.GetResponseStream())
            Dim responseFromServer As String = streamReader.ReadToEnd()
            Dim js As JavaScriptSerializer = New JavaScriptSerializer()
            Dim obj As Tokenclass = js.Deserialize(Of Tokenclass)(responseFromServer)
    
            GetuserProfile(obj.access_token)
    
        End Sub
    
        Public Sub GetuserProfile(ByVal accesstoken As String)
    
            Dim url As String = "https://openidconnect.googleapis.com/v1/userinfo?alt=json&access_token=" & accesstoken & ""
            Dim request As WebRequest = WebRequest.Create(url)
            request.Credentials = CredentialCache.DefaultCredentials
            Dim response As WebResponse = request.GetResponse()
            Dim dataStream As Stream = response.GetResponseStream()
            Dim reader As StreamReader = New StreamReader(dataStream)
            Dim responseFromServer As String = reader.ReadToEnd()
            reader.Close()
            response.Close()
            Dim js As JavaScriptSerializer = New JavaScriptSerializer()
            Dim userinfo As Userclass = js.Deserialize(Of Userclass)(responseFromServer)
    
            If IsNothing(userinfo.email) = True Then
                Page.Response.Redirect("/******.aspx", False)
            Else
                Page.Response.Redirect("/*********.aspx", False)
                'start login
            End If
    
        End Sub
    
    End Class

    The email information i got:

    Best Regard,

    Yang Shen

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, March 16, 2020 3:45 AM

All replies

  • User944339287 posted

    Sorry all, i have tried changed to scope=openid , It's working for certain account but not all.. any idea?

    Below is my code to return user data after obtained access token.

    I get various information about the user such as family name, first name, gender, picture, etc. but it does not return the user's email.

    How do I retrieve the user's email address? Do I have the wrong scope or am I calling the wrong API? I feel like this should be very simple but I have literally been trying to figure this out for hours and I cannot find an API and scope combination that consistently provides the user's email address.

    NOTE: I have changed url to https://openidconnect.googleapis.com/v1/userinfo but not working as expected.

            Dim url As String = "https://www.googleapis.com/oauth2/v2/userinfo?alt=json&access_token=" & accesstoken & ""
            Dim request As WebRequest = WebRequest.Create(url)
            request.Credentials = CredentialCache.DefaultCredentials
            Dim response As WebResponse = request.GetResponse()
            Dim dataStream As Stream = response.GetResponseStream()
            Dim reader As StreamReader = New StreamReader(dataStream)
            Dim responseFromServer As String = reader.ReadToEnd()
            reader.Close()
            response.Close()
            Dim js As JavaScriptSerializer = New JavaScriptSerializer()
            Dim userinfo As Userclass = js.Deserialize(Of Userclass)(responseFromServer)



    Thursday, March 12, 2020 3:12 AM
  • User-719153870 posted

    Hi kengkit,

    According to the link Authentication URI parameters, "In addition to these OpenID-specific scopes, your scope argument can also include other scope values. All scope values must be space-separated. For example, if you wanted per-file access to a user's Google Drive, your scope parameter might be openid profile email", does this mean you can set the scope value like "scope = openid profile email" and you can get the email information?

    Is it possible you could provide more complete code so that we can reproduce the issue?

    Best Regard,

    Yang Shen

    Friday, March 13, 2020 2:28 AM
  • User944339287 posted

    Hi Yang Shen,

    LoginPage.aspx

        Protected Sub lbtn_googleLogin_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles lbtn_googleLogin.Click
    
            Dim clientid As String = "XXXXXXXXXXXXXXXXX"
            Dim clientsecret As String = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
            Dim redirection_url As String = "http://localhost:51016/website/googleLogin.aspx"
            Dim url As String = "https://accounts.google.com/o/oauth2/v2/auth?scope=openid&include_granted_scopes=true&redirect_uri=" & redirection_url & "&response_type=code&client_id=" & clientid & ""
            Response.Redirect(url)
    
        End Sub

    googleLogin.aspx

        Private clientid As String = "XXXXXXXXXXXXXXX"
        Private clientsecret As String = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
        Private redirection_url As String = "http://localhost:51016/website/googleLogin.aspx"
        Private url As String = "https://accounts.google.com/o/oauth2/token"
    
        Public Class Tokenclass
            Public Property access_token As String
            Public Property token_type As String
            Public Property expires_in As Integer
            Public Property refresh_token As String
        End Class
    
        Public Class Userclass
            Public Property id As String
            Public Property name As String
            Public Property given_name As String
            Public Property family_name As String
            Public Property gender As String
            Public Property email As String
            Public Property picture As String
        End Class
    
        Public Sub GetToken(ByVal code As String)
    
            Dim poststring As String = "grant_type=authorization_code&code=" & code & "&client_id=" & clientid & "&client_secret=" & clientsecret & "&redirect_uri=" & redirection_url & ""
            Dim request = CType(WebRequest.Create(url), HttpWebRequest)
            request.ContentType = "application/x-www-form-urlencoded"
            request.Method = "POST"
            Dim utfenc As UTF8Encoding = New UTF8Encoding()
            Dim bytes As Byte() = utfenc.GetBytes(poststring)
            Dim outputstream As Stream = Nothing
    
            Try
                request.ContentLength = bytes.Length
                outputstream = request.GetRequestStream()
                outputstream.Write(bytes, 0, bytes.Length)
            Catch ex As Exception
                Page.Response.Write(ex.Message)
            End Try
    
            Dim response = CType(request.GetResponse(), HttpWebResponse)
            Dim streamReader = New StreamReader(response.GetResponseStream())
            Dim responseFromServer As String = streamReader.ReadToEnd()
            Dim js As JavaScriptSerializer = New JavaScriptSerializer()
            Dim obj As Tokenclass = js.Deserialize(Of Tokenclass)(responseFromServer)
    
            GetuserProfile(obj.access_token)
    
        End Sub
    
        Public Sub GetuserProfile(ByVal accesstoken As String)
    
            Dim url As String = "https://openidconnect.googleapis.com/v1/userinfo?alt=json&access_token=" & accesstoken & ""
            Dim request As WebRequest = WebRequest.Create(url)
            request.Credentials = CredentialCache.DefaultCredentials
            Dim response As WebResponse = request.GetResponse()
            Dim dataStream As Stream = response.GetResponseStream()
            Dim reader As StreamReader = New StreamReader(dataStream)
            Dim responseFromServer As String = reader.ReadToEnd()
            reader.Close()
            response.Close()
            Dim js As JavaScriptSerializer = New JavaScriptSerializer()
            Dim userinfo As Userclass = js.Deserialize(Of Userclass)(responseFromServer)
    
            If IsNothing(userinfo.email) = True Then
                Page.Response.Redirect("/message/account-invalid-access/", False)
            Else
                'start login
            End If    
    
        End Sub
    
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
            If Page.IsPostBack = False Then
                If Request.QueryString("code") IsNot Nothing Then
                    GetToken(Request.QueryString("code").ToString())
                Else
                    Response.Redirect("/home/")
                End If
            End If
    
        End Sub
    




    Friday, March 13, 2020 5:21 AM
  • User-719153870 posted

    Hi kengkit,

    Sorry for the late reply and thanks for the code. Have you tried the suggestion i provided? I mean " you can set the scope value like "scope = openid profile email"".

    I created a demo based on your code and reproduced the issue(can not get email information), then changed the scope parameter as i said and the demo works and we can get email information now.

    Below is the demo, maybe you want to refer:

    LoginPage.aspx:

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
                <asp:LinkButton ID="googleLogin" runat="server" OnClick="googleLogin_Click">googleLogin</asp:LinkButton>
            </div>
        </form>
    </body>
    </html>

    LoginPage.aspx.vb:

    Public Class LoginPage
        Inherits System.Web.UI.Page
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
        End Sub
    
        Protected Sub googleLogin_Click(sender As Object, e As EventArgs)
            Dim clientid As String = "**********-*****************************.apps.googleusercontent.com"
            Dim clientsecret As String = "*********************"
            Dim redirection_url As String = "https://localhost:44325/googleLogin.aspx"
            Dim url As String = "https://accounts.google.com/o/oauth2/v2/auth?scope=openid profile email&include_granted_scopes=true&redirect_uri=" & redirection_url & "&response_type=code&client_id=" & clientid & ""
            Response.Redirect(url)
        End Sub
    
    End Class

    googleLogin.aspx.vb:

    Imports System.IO
    Imports System.Net
    Imports System.Web.Script.Serialization
    Public Class googleLogin
        Inherits System.Web.UI.Page
    
        Private clientid As String = "*************-**************************.apps.googleusercontent.com"
        Private clientsecret As String = "*************************"
        Private redirection_url As String = "https://localhost:44325/googleLogin.aspx"
        Private url As String = "https://accounts.google.com/o/oauth2/token"
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            If Page.IsPostBack = False Then
                If Request.QueryString("code") IsNot Nothing Then
                    GetToken(Request.QueryString("code").ToString())
                Else
                    Response.Redirect("/*****.aspx")
                End If
            End If
        End Sub
    
        Public Class Tokenclass
            Public Property access_token As String
            Public Property token_type As String
            Public Property expires_in As Integer
            Public Property refresh_token As String
        End Class
    
        Public Class Userclass
            Public Property id As String
            Public Property name As String
            Public Property given_name As String
            Public Property family_name As String
            Public Property gender As String
            Public Property email As String
            Public Property picture As String
        End Class
    
        Public Sub GetToken(ByVal code As String)
    
            Dim poststring As String = "grant_type=authorization_code&code=" & code & "&client_id=" & clientid & "&client_secret=" & clientsecret & "&redirect_uri=" & redirection_url & ""
            Dim request = CType(WebRequest.Create(url), HttpWebRequest)
            request.ContentType = "application/x-www-form-urlencoded"
            request.Method = "POST"
            Dim utfenc As UTF8Encoding = New UTF8Encoding()
            Dim bytes As Byte() = utfenc.GetBytes(poststring)
            Dim outputstream As Stream = Nothing
    
            Try
                request.ContentLength = bytes.Length
                outputstream = request.GetRequestStream()
                outputstream.Write(bytes, 0, bytes.Length)
            Catch ex As Exception
                Page.Response.Write(ex.Message)
            End Try
    
            Dim response = CType(request.GetResponse(), HttpWebResponse)
            Dim streamReader = New StreamReader(response.GetResponseStream())
            Dim responseFromServer As String = streamReader.ReadToEnd()
            Dim js As JavaScriptSerializer = New JavaScriptSerializer()
            Dim obj As Tokenclass = js.Deserialize(Of Tokenclass)(responseFromServer)
    
            GetuserProfile(obj.access_token)
    
        End Sub
    
        Public Sub GetuserProfile(ByVal accesstoken As String)
    
            Dim url As String = "https://openidconnect.googleapis.com/v1/userinfo?alt=json&access_token=" & accesstoken & ""
            Dim request As WebRequest = WebRequest.Create(url)
            request.Credentials = CredentialCache.DefaultCredentials
            Dim response As WebResponse = request.GetResponse()
            Dim dataStream As Stream = response.GetResponseStream()
            Dim reader As StreamReader = New StreamReader(dataStream)
            Dim responseFromServer As String = reader.ReadToEnd()
            reader.Close()
            response.Close()
            Dim js As JavaScriptSerializer = New JavaScriptSerializer()
            Dim userinfo As Userclass = js.Deserialize(Of Userclass)(responseFromServer)
    
            If IsNothing(userinfo.email) = True Then
                Page.Response.Redirect("/******.aspx", False)
            Else
                Page.Response.Redirect("/*********.aspx", False)
                'start login
            End If
    
        End Sub
    
    End Class

    The email information i got:

    Best Regard,

    Yang Shen

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, March 16, 2020 3:45 AM