Webforms的Google.Apis.Auth.OAuth

时间:2014-04-07 11:54:00

标签: .net oauth google-api

有没有人有一个简单的例子如何在C#Webforms中使用Google.Apis.Auth.OAuth? 我只能找到MVC。

2 个答案:

答案 0 :(得分:1)

我为转换控制台应用程序的原始示例而苦苦挣扎了一段时间-确实是为了展示您的应用程序如何访问用户自己的Google表格。

https://developers.google.com/sheets/api/quickstart/dotnet

有一个基于MVC的示例-不能很好地适用于Web表单-但是,这确实适用于网站访问任何用户数据

https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#web-applications-aspnet-mvc

这两个过程的一部分-是您被发送到Google的API,以授予对用户数据的访问权限,例如访问您拥有的Google工作表。授予访问权限后,它会返回您指定的返回网址。

控制台示例打开一个用于授予访问权限的浏览器。

一旦授予访问权限,即会保存一个文件,该文件存储此权限,无需再次请求。

我将控制台应用程序代码转换为可以在Web窗体中运行,但这需要我复制凭据文件(该文件是使用控制台应用程序示例生成的)。无法生成凭据文件,因为它试图使IIS启动浏览器来获取IIS用户无权执行的授权(无论如何也无法在生产环境中使用)。如果将文件复制到IIS可以查看的位置,它仍然可以工作(如果凭据文件存在,它将跳过打开浏览器的权限)。

这是我的示例(用于Webform的代码):

Imports Google.Apis.Auth.OAuth2
Imports Google.Apis.Sheets.v4
Imports Google.Apis.Sheets.v4.Data
Imports Google.Apis.Services
Imports Google.Apis.Util.Store
Imports System.Collections.Generic
Imports System.Threading

Private Sub btnImportData_Click(sender As Object, e As EventArgs) Handles btnImportData.Click

    Dim ApplicationName As String = "Google Sheets API .NET Quickstart"
    'Dim credPath As String = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)
    'credPath = Path.Combine(credPath, ".credentials/sheets.googleapis.com-dotnet-quickstart.json")

    Dim credPath As String = Server.MapPath("~/YourPathToCredentials/google-api-credentials")

    Dim CS As New ClientSecrets With {
            .ClientId = "-- YOUR CLIENT ID --",
            .ClientSecret = "-- YOUR CLIENT SECRET --"
        }
    'Dim Scopes As String() = {SheetsService.Scope.SpreadsheetsReadonly}
    Dim Scopes As IEnumerable(Of String) = {SheetsService.Scope.Drive}
    'Dim DataStore = New FileDataStore("Drive.Api.Auth.Store")
    Dim credential As UserCredential = GoogleWebAuthorizationBroker.AuthorizeAsync(CS, Scopes, "user", CancellationToken.None, New FileDataStore(credPath, True)).Result
    Diagnostics.Debug.WriteLine("Credential file saved to: " & credPath)

    Dim service = New SheetsService(New BaseClientService.Initializer() With {
        .HttpClientInitializer = credential,
        .ApplicationName = ApplicationName
    })
    'Glossary Spreadsheet used as data repository for Glossary BETA Google Forms prototype
    Dim spreadsheetId As String = "-- YOUR GOOGLE SHEET ID --"
    Dim range As String = "Form responses 1!A2:G"
    Dim request As SpreadsheetsResource.ValuesResource.GetRequest = service.Spreadsheets.Values.[Get](spreadsheetId, range)
    Dim response As ValueRange = request.Execute()
    Dim values As IList(Of IList(Of Object)) = response.Values

    If values IsNot Nothing AndAlso values.Count > 0 Then
        Diagnostics.Debug.WriteLine("Category, Term, Definition")

        For Each row In values
            Diagnostics.Debug.WriteLine("{0}, {1}, {2}", row(3), row(1), row(2))
        Next
    Else
        Diagnostics.Debug.WriteLine("No data found.")
    End If
End Sub

一种更相关且更容易的方法是一种完全不同的类型,该类型专门用于服务器到服务器的通信,即Google API背后的网络表单代码。

为此,您需要一个“服务帐户”-这些凭据在api后端上创建,然后可以由Web应用程序以代码形式使用-正是我一直在寻找的用例(始终使用相同的数据存储)由我在Google表格中拥有)。

https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#service-account

https://developers.google.com/identity/protocols/OAuth2ServiceAccount

这是我使用Google服务帐户的示例。

注意-我在Google API控制台上创建了一个服务帐户-这将为该后台帐户生成一个电子邮件地址-我必须对此感兴趣的工作表授予此电子邮件的许可。Google上的代码示例为适用于较早的P12格式-而API控制台建议使用较新的JSON格式。我的示例代码已修改为使用更现代的JSON格式。创建服务帐户时,它会为您提供文件下载,请确保将副本安全地保存在某个地方,因为您将无法重新生成它。如果您这样做的话,这还不是世界末日,但您将无法再次使用该帐户,则必须创建一个新帐户并授予该权限。

Imports System.Data
Imports Google.Apis.Auth.OAuth2
Imports Google.Apis.Sheets.v4
Imports Google.Apis.Sheets.v4.Data
Imports Google.Apis.Services
Imports Google.Apis.Util.Store
Imports System.Collections.Generic
Imports System.Threading
Imports System.IO

    Public Sub ImportGlossaryGoogleSheetData_ServiceAccount()
        Diagnostics.Debug.WriteLine("=====================================")
        Diagnostics.Debug.WriteLine("Import Glossary using Service Account")
        Diagnostics.Debug.WriteLine("=====================================")
        Dim credPath As String = Server.MapPath("~/YourPathToCredentials/google-api-credentials/credentialfile.json")
        Dim credential As ServiceAccountCredential
        Using stream As New FileStream(credPath, FileMode.Open, FileAccess.Read, FileShare.Read)
            credential = GoogleCredential.FromStream(stream).CreateScoped({SheetsService.Scope.Drive}).UnderlyingCredential
        End Using
        Dim service = New SheetsService(New BaseClientService.Initializer() With {
            .HttpClientInitializer = credential,
            .ApplicationName = "YOUR APP NAME"
        })
        'Glossary Spreadsheet used as data repository for Glossary BETA Google Forms prototype
        Dim spreadsheetId As String = "-- YOUR GOOGLE SHEET ID --"
        Dim range As String = "Form responses 1!A2:G"
        Dim request As SpreadsheetsResource.ValuesResource.GetRequest = service.Spreadsheets.Values.[Get](spreadsheetId, range)
        Dim response As ValueRange = request.Execute()
        Dim values As IList(Of IList(Of Object)) = response.Values
        If values IsNot Nothing AndAlso values.Count > 0 Then
            Diagnostics.Debug.WriteLine("Category, Term, Definition")

            For Each row In values
                Diagnostics.Debug.WriteLine("{0}, {1}, {2}", row(3), row(1), row(2))
            Next
        Else
            Diagnostics.Debug.WriteLine("No data found.")
        End If
    End Sub

我希望这可以解释我对Google所提供的不同方法的发现:

  • OAuth-一种通用方法,允许您的代码权限查看 用户数据,例如您的网站正在查看用户Google中的数据 工作表。

  • 服务帐户-服务器到服务器对Google API的访问权限-例如您的 网站使用Google API查看特定数据,即硬编码为 查看您拥有的数据并为其生成凭据 API后端。

答案 1 :(得分:0)

已经有一段时间但我认为这可能对某人有用:

GoogleFlowMetaData:

public class GoogleFlowMetaData
{
    private static readonly IAuthorizationCodeFlow flow =
    new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
    {
        ClientSecrets = new ClientSecrets
        {
            ClientId = "your client ID",
            ClientSecret = "your client secret"
        },
        Scopes = new[] { CalendarService.Scope.Drive/*or any service you want*/ },
        DataStore = new FileDataStore("Drive.Api.Auth.Store")
    });

    public IAuthorizationCodeFlow Flow
    {
        get { return flow; }
    }
}

AuthorizationCodeApp:

public class AuthorizationCodeApp : AuthorizationCodeWebApp
{
    private readonly GoogleFlowMetaData flowData;
    private readonly string redirectUri;
    private readonly string state;
    private readonly string userID;
    public GoogleFlowMetaData FlowData { get { return flowData; } }
    public AuthorizationCodeApp(GoogleFlowMetaData flowData, string redirectUri, string state, string userID):base(
        flowData.Flow,redirectUri,state)
    {
        this.redirectUri = redirectUri;
        this.state = state;
        this.userID = userID;
    }
    public Task<AuthResult> AuthorizeAsync(CancellationToken taskCancellationToken)
    {
        return base.AuthorizeAsync(userID, taskCancellationToken);
    }
}

现在可以在任何地方运行Async任务,只需要定义类似的内容:

 public async Task<string> IndexAsync(CancellationToken cancellationToken)
    {
        var result = await new AuthorizationCodeApp(new GoogleFlowMetaData(), "http://localhost:4356/API/GAuth","","beebee").
            AuthorizeAsync(cancellationToken);

        if (result.Credential != null)
        {
           var service = new DriveService(new BaseClientService.Initializer
                    {
                        // YOUR CODE SHOULD BE HERE..
                    });

            }
            else
        {
            return result.RedirectUri;
        }
    }

以异步方式调用上述函数:

var cancelToken = new CancellationTokenSource();
var z = Task.Factory.StartNew(() => IndexAsync(cancelToken.Token));