【问题标题】:How to authenticate to Google Cloud Printing如何向 Google 云打印进行身份验证
【发布时间】:2018-12-20 18:47:28
【问题描述】:

我正在制作一个应用,它需要通过 Google 云打印将打印作业发送到我拥有的两台打印机(即,这些打印机始终是同一个,不属于用户)。我已经使用 Google 云打印设置了打印机,现在可以从我的 Google 帐户访问它。

现在,我如何通过 API 访问此帐户的打印机?我找到了一些文档here,上面说我需要在发出请求时对自己进行身份验证。 在我看来应该使用OAuth2 进行身份验证。但是对于初学者来说,缺乏关于如何做到这一点的说明。我已经获得了我的 OAuth 客户端 ID 和密码(OAuth 链接中的第 1 步)。但是对于第 2 步,我不知道该怎么做。

上面写着:

在您的应用程序可以使用 Google 访问私人数据之前 API,它必须获得一个访问令牌来授予对该 API 的访问权限。一种 单个访问令牌可以授予对多个访问权限的不同程度的访问权限 API。

但没有说明如何获取此访问令牌。我查看了this SO question OP 似乎能够在哪里获得此访问令牌,但我不明白他是如何做到的。

有人能解释一下如何获取访问令牌以用于 Google 云打印吗?或者一个很好的资源来解释如何?

附言。打印功能由 firebase 功能触发。考虑到 Firebase 也是由 Google 制造的,这是否有助于我们获得访问令牌?

【问题讨论】:

标签: firebase http printing oauth-2.0 google-cloud-print


【解决方案1】:

我遇到了同样的问题并想出了这个两步解决方案:

  1. 在您的Google Cloud Console 中创建一个OAuth2 客户端,如here 所述 并从控制台下载其客户端凭据,并将其 json 内容复制并粘贴到下面代码 sn-p 中的 credJSON
  2. 运行以下代码。
    • 点击 auth 链接并授权您的 OAuth2 客户端使用您的 Google 帐户访问 Googel 云打印机。
    • 将授权码复制并粘贴到脚本中
    • 获得刷新令牌后,请确保将其存储在变量 refreshToken
    • 不要忘记更新代理名称。
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/google/cloud-print-connector/gcp"
    "github.com/google/cloud-print-connector/lib"
    "github.com/google/uuid"
    "golang.org/x/oauth2"
    "golang.org/x/oauth2/google"
)

var (
    credJSON     = ``
    refreshToken = ""

    // Find the proxy in the Advanced Details of your printer at https://www.google.com/cloudprint#printers
    proxy = "HP"
)

func main() {
    // Obtain the OAuth config
    config, err := google.ConfigFromJSON([]byte(credJSON), gcp.ScopeCloudPrint)
    if err != nil {
        log.Fatalf("Failed to obtain OAuth config: %v", err)
    }

    // If no request token is present, obtain a new one
    if refreshToken == "" {
        // Get the auth link
        authLink := config.AuthCodeURL(uuid.New().String(), oauth2.AccessTypeOffline)
        log.Printf("Follow the link to obtain an auth code: %s", authLink)

        fmt.Printf("Paste your auth code here: ")
        var code string
        fmt.Scanln(&code)

        // Get a token form the auth code
        token, err := config.Exchange(context.Background(), code, oauth2.AccessTypeOffline)
        if err != nil {
            log.Fatalf("Failed to obtain OAuth token: %v", err)
        }
        if token.RefreshToken != "" {
            refreshToken = token.RefreshToken
        } else {
            refreshToken = token.AccessToken
        }
        log.Printf("Refresh token: %s", refreshToken)
    }

    // Connect to Google Cloud Print
    jobCh := make(chan *lib.Job)
    client, err := gcp.NewGoogleCloudPrint(lib.DefaultConfig.GCPBaseURL, refreshToken, refreshToken, proxy, config.ClientID, config.ClientSecret, config.Endpoint.AuthURL, config.Endpoint.TokenURL, lib.DefaultConfig.NativeJobQueueSize, jobCh, true)
    if err != nil {
        log.Fatalf("Failed to connect to GCP: %v", err)
    }

    // List all printers
    printers, _, err := client.ListPrinters()
    if err != nil {
        log.Fatalf("Failed to list printers: %v", err)
    }
    for _, p := range printers {
        log.Printf("Name: %s UUID: %s", p.Name, p.UUID)
    }
}

【讨论】:

    【解决方案2】:

    请参考以下文档:

    https://developers.google.com/identity/protocols/OAuth2ServiceAccount?authuser=1
    

    我遵循了文档中指定的相同步骤,并且能够获取访问令牌。首先创建谷歌服务帐户,选择提供新的私钥。您将拥有服务帐户电子邮件地址和私钥。使用这些凭据,您可以获得访问令牌。下面是Golang的源码,对你有帮助。

    package main
    
    import (
    "fmt"
    "github.com/dgrijalva/jwt-go"
    "net/http"
    "encoding/json"
    "bytes"
    )
    
    type MyCustomClaims struct {
        Scope string `json:"scope,omitempty"`
        jwt.StandardClaims
    }
    
    type Toke struct {
        Access string `json:"access_token,omitempty"`
        Type string `json:"token_type,omitempty"`
        Expire string `json:"expires_in,omitempty"`
    }
    
    func main() {
    
        key := []byte("<your private key>")
    
        key1, _ := jwt.ParseRSAPrivateKeyFromPEM(key)
    
        claims := MyCustomClaims{
            "https://www.googleapis.com/auth/cloudprint",
            jwt.StandardClaims{
                IssuedAt: <currrent-epoch-time>,         // eg 1234566000
                ExpiresAt: <currrent-epoch-time + 3600>, // 3600 secs = 1hour, so expires in 1 hour, eg 1234569600
                Issuer:    "<your service account email>",
                Audience: "https://www.googleapis.com/oauth2/v4/token",
            },
        }
        token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
        ss, err := token.SignedString(key1)
        if err != nil {
            fmt.Println(err)
        }
    
        fmt.Println(ss)
        url := "https://www.googleapis.com/oauth2/v4/token"
        any := "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=" + ss
        a := []byte(any)
        b := bytes.NewBuffer(a)
        var tok Toke
    
        req, err := http.NewRequest("POST", url, b)
        req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    
        client := &http.Client{}
    
        resp, err := client.Do(req)
        if err != nil {
            panic(err)
        } else {
            json.NewDecoder(resp.Body).Decode(&tok)
        }
        fmt.Println("----------- Access Token -----------------")
        fmt.Println("Access: ", tok.Access)
    }
    

    【讨论】:

    • 这是一个仅链接的答案。合作解决现有的问题。
    • 我的意思是将它添加到您的答案中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    • 1970-01-01
    • 2019-11-09
    相关资源
    最近更新 更多