.net Google通过服务帐户访问API

.net Google通过服务帐户访问API,.net,vb.net,google-api,google-contacts-api,service-accounts,.net,Vb.net,Google Api,Google Contacts Api,Service Accounts,我制作了一个从我的谷歌账户中插入、显示和删除联系人的应用程序。直到两周前,它还可以正常工作,但在谷歌停止支持客户端登录(用户/密码访问)后,迫使使用OAuth2通过令牌获得访问权限,这在这里是一个巨大的问题(我不擅长软件开发) 通过更新后的广泛搜索,我将代码调整为以下逻辑: Const service_id = "My_Service_ID.apps.googleusercontent.com" Const service_email = "My_Service_Account_Email@de

我制作了一个从我的谷歌账户中插入、显示和删除联系人的应用程序。直到两周前,它还可以正常工作,但在谷歌停止支持客户端登录(用户/密码访问)后,迫使使用OAuth2通过令牌获得访问权限,这在这里是一个巨大的问题(我不擅长软件开发)

通过更新后的广泛搜索,我将代码调整为以下逻辑:

Const service_id = "My_Service_ID.apps.googleusercontent.com"
Const service_email = "My_Service_Account_Email@developer.gserviceaccount.com"
Const nome_aplicacao = "My_Application_Name"
Const user_id = service_email
1.使用从p12密钥获得的凭据创建令牌,并使用该令牌返回contactsRequest:

Private Function CriaContactRequest() As ContactsRequest
    Try
        Dim certificate As New X509Certificate2(Server.MapPath("/chave/key.p12"), "notasecret", X509KeyStorageFlags.Exportable)
        Dim credential As New ServiceAccountCredential(New ServiceAccountCredential.Initializer(service_email) With { _
             .Scopes = New String() {"https://www.google.com/m8/feeds https://www.google.com/m8/feeds/groups/default/full"}
        }.FromCertificate(certificate))
        credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Wait()
        Dim rs = New RequestSettings(nome_aplicacao) With { _
                .OAuth2Parameters = New OAuth2Parameters() With { _
                    .AccessToken = credential.Token.AccessToken, .RefreshToken = "6000" _
                } _
            }
        Dim cr As New ContactsRequest(rs)
        Return cr
    Catch ex As Exception
        Throw ex
    End Try
End Function
2.要显示所有联系人:

Public Sub ExibeContatos()
    Try
        Dim f As Feed(Of Contact) = CriaContactRequest().GetContacts()
        If f.Entries.Count > 0 Then
            ' Loop to show contacts here....
        Else
            Response.Write("Não existem contatos.")
        End If
    Catch ex As HttpException
        Response.Write("Erro Exibe Contatos: " & ex.Message)
    End Try
End Sub
Public Sub InsereContatoGoogle(oContato As Contact)
    Try
        Dim feedUri As New Uri(ContactsQuery.CreateContactsUri(user_id))
        InserenNoGrupoPrincipal(oContato)
        CriaContactRequest().Insert(feedUri, oContato)
    Catch ex As Exception
        Response.Write("Erro Insere Contato Google: " & ex.Message)
    End Try
End Sub
3.要插入联系人:

Public Sub ExibeContatos()
    Try
        Dim f As Feed(Of Contact) = CriaContactRequest().GetContacts()
        If f.Entries.Count > 0 Then
            ' Loop to show contacts here....
        Else
            Response.Write("Não existem contatos.")
        End If
    Catch ex As HttpException
        Response.Write("Erro Exibe Contatos: " & ex.Message)
    End Try
End Sub
Public Sub InsereContatoGoogle(oContato As Contact)
    Try
        Dim feedUri As New Uri(ContactsQuery.CreateContactsUri(user_id))
        InserenNoGrupoPrincipal(oContato)
        CriaContactRequest().Insert(feedUri, oContato)
    Catch ex As Exception
        Response.Write("Erro Insere Contato Google: " & ex.Message)
    End Try
End Sub
4.在插入联系人之前,将其分配给“我的联系人”(饲料上的第一组所有组):

5.根据填充有电子邮件的向量删除联系人的代码:

Public Sub ApagaContato(emailToExclude As String())
    Dim query As ContactsQuery = New ContactsQuery(ContactsQuery.CreateContactsUri(user_id))
    query.BaseAddress = emailToExclude(0)
    Dim feed As Feed(Of Contact)
    Try
        Dim cr As ContactsRequest = CriaContactRequest()
        feed = cr.GetContacts()
        For Each c As Contact In feed.Entries
            For x As Integer = 0 To c.Emails.Count - 1
                For y As Integer = 0 To emailToExclude.Length - 1
                    If c.Emails.Item(x).Address = emailToExclude(y) Then
                        cr.Delete(c)
                    End If
                Next
            Next
        Next
    Catch ex As Exception
        Response.Write("Erro Apaga Contato: " & ex.Message)
    End Try
End Sub
这些功能正在发挥作用,但没有达到预期效果:我可以正常插入新条目、删除和查看条目,但可以在我的Google帐户中“
myaccount@google.com
“什么也没发生。在搜索了一些forun之后,我怀疑它们在服务帐户“
myserviceaccount@developer.gserviceaccount.com
”,这就是问题所在:


有人可以指定此代码的范围、凭据或其他部分中的错误,以及我如何使服务帐户访问保存在我的“myaccount@google.com“联系人?

我认为您不能为此使用服务帐户。服务帐户是它自己的SUDO用户,它有一个驱动器帐户,一个谷歌日历帐户,可能还有一个联系人帐户,就像其他任何用户一样

也就是说,除非你给它访问权限,否则它无法访问你的个人谷歌联系人。据我所知,没有办法授予其他人访问你的联系人的权限。你一直在做的是将用户插入服务帐户Google Contacts帐户


我建议您考虑使用Oauth2,使用Google帐户对代码进行一次身份验证,然后存储刷新令牌。下次运行代码时,可以使用刷新令牌为您获取新的访问令牌。您必须在第一次执行身份验证过程

在此范围内解决:

Private Function CriaContactRequest(Optional scope As String = "https://www.google.com/m8/feeds https://www.google.com/m8/feeds/groups/default/full") As ContactsRequest
    Try
        Dim rs = New RequestSettings(nome_aplicacao) With { _
                        .OAuth2Parameters = New OAuth2Parameters() With { _
                        .AccessToken = refresh_token, _
                        .RefreshToken = refresh_token, _
                        .ClientId = client_id, _
                        .ClientSecret = client_secret, _
                        .RedirectUri = redirect_uri, _
                        .Scope = scope _
                    } _
                }
        Dim cr As New ContactsRequest(rs)
        Return cr
    Catch ex As Exception
        Throw ex
    End Try
End Function

我错误地认为refresh\u token属性用于指示令牌刷新时间,而不是可以存储的代码。

谢谢,我尝试使用服务帐户而不是客户端访问,因为我不需要提示,我认为这是最好的选择,但它不是这样工作的。使用从OAuth游乐场生成的刷新令牌,所有这些任务都运行良好:代码比初始post少,并且不需要p12键