【问题标题】:401 Unauthorized - Google Drive API401 未经授权 - Google Drive API
【发布时间】:2015-06-12 19:01:49
【问题描述】:

我是第一次使用 Google API,我在尝试使用文件对象“downloadUrl”属性下载文件时遇到问题。我目前正在使用带有关联服务帐户电子邮件和 P12 证书的“服务帐户”选项。

但是,返回“https://doc-08-68-docs.googleusercontent.com/docs/securesc/bteg36c1tifegg79l2ov17og25612tet/gk7kn52ahe4d0to7d6hte9f0f2hv47e4/1434132000000/11750183130219432819/11750183130219432819/0BziIKv2_NWCxc3RhcnRlcl9maWxl?e=download&gd=true”的 URL 会返回 401 - 未经授权的响应。

Imports System.Collections.Generic
Imports System.Security.Cryptography.X509Certificates
Imports System.IO

Imports Google.Apis.Drive.v2
Imports Google.Apis.Drive.v2.Data
Imports Google.Apis.Services
Imports Google.Apis.Auth.OAuth2

Namespace Videos

    Partial Class List
        Inherits System.Web.UI.UserControl

        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

            Const serviceAccountEmail As String = "@developer.gserviceaccount.com"

            Dim certificate = New X509Certificate2(
                Server.MapPath("~/bin/key.p12"),
                "notasecret",
                X509KeyStorageFlags.MachineKeySet Or X509KeyStorageFlags.PersistKeySet Or X509KeyStorageFlags.Exportable
            )

            Dim credential = New ServiceAccountCredential(
               New ServiceAccountCredential.Initializer(serviceAccountEmail) With {
                   .Scopes = New String() {DriveService.Scope.Drive}
               }.FromCertificate(certificate)
            )

            Dim service = New DriveService(
                New BaseClientService.Initializer() With {
                    .HttpClientInitializer = credential,
                    .ApplicationName = "LexVid-VideoEncode/1.0"
                }
            )

            UxFiles.DataSource = RetrieveAllFiles(service)
            UxFiles.DataBind()

        End Sub

        Public Shared Function RetrieveAllFiles(service As DriveService) As List(Of Data.File)

            Dim result = New List(Of Data.File)()
            Dim request As FilesResource.ListRequest = service.Files.List()

            Do

                Try

                    Dim files As FileList = request.Execute()

                    result.AddRange(files.Items)
                    request.PageToken = files.NextPageToken

                Catch e As Exception
                    request.PageToken = Nothing
                End Try

            Loop While (Not String.IsNullOrEmpty(request.PageToken))

            Return result

        End Function


        Public Shared Function DownloadFile(ByVal service As DriveService, ByVal file As Data.File) As System.IO.Stream

            If (Not String.IsNullOrEmpty(file.DownloadUrl)) Then

                Try

                    Dim x = service.HttpClient.GetByteArrayAsync(file.DownloadUrl)
                    Dim result As [Byte]() = x.Result

                    Return New MemoryStream(result)

                Catch e As Exception
                    Return Nothing
                End Try

            Else
                Return Nothing
            End If

        End Function

        Protected Sub UxFiles_ItemDataBound(ByVal sender As Object, ByVal e As ListViewItemEventArgs) Handles UxFiles.ItemDataBound

            Dim dataItem = CType(e.Item.DataItem, Data.File)

            Dim file = CType(e.Item.FindControl("UxFile"), HyperLink)
            file.NavigateUrl = dataItem.DownloadUrl
            file.Text = dataItem.Title

        End Sub

    End Class

End Namespace

【问题讨论】:

  • 我不熟悉 .net 库,所以这是一个猜测。我怀疑您用于下载 URL 的技术未能正确设置 Authorization: 标头。跟踪 http 流量并查看 httprequest 标头的内容。如果您只是在 .net 中构建 http GET 并自己设置标头,完全绕过库,您可能会更快到达那里。
  • 好的,如果我无法让 .NET 库配合,那将是我的下一次尝试。我必须对 Aspose.Words for Cloud 做同样的事情。

标签: asp.net .net vb.net google-drive-api


【解决方案1】:

我通过反复试验解决了这个问题。虽然我现在手动构建链接,但请求令牌甚至不再需要。但是,我在这里发帖以防其他人正在寻求解决类似问题。

Imports System.Collections.Generic
Imports System.Security.Cryptography.X509Certificates
Imports System.IO
Imports System.Threading

Imports Google.Apis.Drive.v2
Imports Google.Apis.Drive.v2.Data
Imports Google.Apis.Services
Imports Google.Apis.Auth.OAuth2

Namespace Videos

    Partial Class List
        Inherits System.Web.UI.UserControl

        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

            Const serviceAccountEmail As String = "@developer.gserviceaccount.com"

            Dim certificate = New X509Certificate2(
                Server.MapPath("~/bin/key.p12"),
                "notasecret",
                X509KeyStorageFlags.MachineKeySet Or X509KeyStorageFlags.PersistKeySet Or X509KeyStorageFlags.Exportable
            )

            Dim credential As ServiceAccountCredential = New ServiceAccountCredential(
            New ServiceAccountCredential.Initializer(serviceAccountEmail) With {
                .Scopes = New String() {DriveService.Scope.Drive}
            }.FromCertificate(certificate)
            )

            If (credential.RequestAccessTokenAsync(CancellationToken.None).Result) Then

                Dim service = New DriveService(
                    New BaseClientService.Initializer() With {
                        .HttpClientInitializer = credential,
                        .ApplicationName = "LexVid-VideoEncode/1.0"
                    }
                )

                UxFiles.DataSource = RetrieveAllFiles(service)
                UxFiles.DataBind()

            End If

        End Sub

        Public Shared Function RetrieveAllFiles(service As DriveService) As List(Of Data.File)

            Dim result = New List(Of Data.File)()
            Dim request As FilesResource.ListRequest = service.Files.List()

            Do

                Try

                    Const folderID As String = "0B5RLR6VRZsR4fkE5QjVFajg2dzZOMXZLYkNZUVdGbEtNODF0XzVBVGdjMW9ISDF5OE9kM0E"
                    request.Q = String.Format("'{0}' in parents and trashed=false", folderID)
                    Dim files As FileList = request.Execute()

                    result.AddRange(files.Items)
                    request.PageToken = files.NextPageToken

                Catch e As Exception
                    request.PageToken = Nothing
                End Try

            Loop While (Not String.IsNullOrEmpty(request.PageToken))

            Return result

        End Function

        Protected Sub UxFiles_ItemDataBound(ByVal sender As Object, ByVal e As ListViewItemEventArgs) Handles UxFiles.ItemDataBound

            Dim dataItem = CType(e.Item.DataItem, Data.File)

            Const folderID As String = "0B5RLR6VRZsR4fkE5QjVFajg2dzZOMXZLYkNZUVdGbEtNODF0XzVBVGdjMW9ISDF5OE9kM0E"

            Dim file = CType(e.Item.FindControl("UxFile"), HyperLink)
            file.NavigateUrl = String.Format("http://googledrive.com/host/{0}/{1}", folderID, dataItem.Title)
            ' Large files prompt for virus scan; no bypass available.
            ' file.NavigateUrl = String.Format("https://drive.google.com/uc?export=download&id={0}", dataItem.Id)
            file.Text = dataItem.Title

        End Sub

    End Class

End Namespace

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    • 2012-04-04
    • 2014-10-22
    • 2023-03-28
    • 1970-01-01
    • 2019-03-07
    • 2017-09-27
    相关资源
    最近更新 更多