在Go

时间:2016-09-20 15:54:45

标签: go firebase oauth-2.0 jwt firebase-authentication

我正在尝试将新的Firebase实时数据库用于简单的日志记录应用程序。所有与数据库的交互都将来自我的服务器,因此我只需要一个可以读/写任何内容的帐户。

据我所知(文档很糟糕 - 它有很多,但它与自身相矛盾,其中一半是针对'旧的'Firebase,而且通常是一些你没有使用的随机语言) ,我需要创建一个服务帐户,然后使用OAuth创建一个JWT令牌。幸运的是,Go有一些很好的内置库。这是我的代码:

const firebasePostUrl = "https://my-product-logging.firebaseio.com/tests.json"

// Obtained from the Google Cloud API Console
var firebaseServiceAccount map[string]string = map[string]string{
    "type":                        "service_account",
    "project_id":                  "my-product-logging",
    "private_key_id":              "1c35ac0c501617b8f1610113c492a5d3321f4318",
    "private_key":                 "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoblahblahhwWlteuRDrsxmRq+8\ncDGMKcXyDHl3nWdIrWqJcDw=\n-----END PRIVATE KEY-----\n",
    "client_email":                "log-user@my-product-logging.iam.gserviceaccount.com",
    "client_id":                   "101403085113430683797",
    "auth_uri":                    "https://accounts.google.com/o/oauth2/auth",
    "token_uri":                   "https://accounts.google.com/o/oauth2/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_x509_cert_url":        "https://www.googleapis.com/robot/v1/metadata/x509/log-user%40my-product-logging.iam.gserviceaccount.com",
}

func firebaseClient() *http.Client {
    jwtConfig := jwt.Config{
        // Email is the OAuth client identifier used when communicating with
        // the configured OAuth provider.
        Email: firebaseServiceAccount["client_email"],

        // PrivateKey contains the contents of an RSA private key or the
        // contents of a PEM file that contains a private key. The provided
        // private key is used to sign JWT payloads.
        // PEM containers with a passphrase are not supported.
        // Use the following command to convert a PKCS 12 file into a PEM.
        //
        //    $ openssl pkcs12 -in key.p12 -out key.pem -nodes
        //
        PrivateKey: []byte(firebaseServiceAccount["private_key"]),

        // PrivateKeyID contains an optional hint indicating which key is being
        // used.
        PrivateKeyID: firebaseServiceAccount["private_key_id"],

        // Subject is the optional user to impersonate.
        Subject: "",

        // Scopes optionally specifies a list of requested permission scopes.
        Scopes: []string{
            "https://www.googleapis.com/auth/devstorage.readonly",
        },

        // TokenURL is the endpoint required to complete the 2-legged JWT flow.
        TokenURL: firebaseServiceAccount["token_uri"],

        // Expires optionally specifies how long the token is valid for.
        Expires: 0,
    }

    ctx := context.Background()
    return jwtConfig.Client(ctx)
}

func firebaseFunc() {

    authedClient := firebaseClient()

    msg := map[string]string{
        "hello": "there",
        "every": "one",
    }

    data, err := json.Marshal(msg)
    if err != nil {
        log.Fatal("JSON Marshall Error: ", err)
        continue
    }

    resp, err := authedClient.Post(firebasePostUrl, "application/json", bytes.NewReader(data))
    if err != nil {
        log.Fatal("Firebase Error: ", err)
        continue
    }

    log.Print("Firebase Response Code: ", resp.StatusCode)
}

问题是,我总是收到这个错误:

{
  "error" : "invalid_scope",
  "error_description" : "https://www.googleapis.com/auth/devstorage.readonly is not a valid audience string."
}

我认为这是一种错误为invalid_ scope 的类型,描述说它是无效的 audience (我假设JWT aud参数)。

我可以使用什么作为我的范围来允许我读取/写入Firebase数据库(使用默认的"auth != null"规则)?

编辑:我最终找到了答案here

https://www.googleapis.com/auth/firebase

然而现在它在实际发布时给了我403响应。

{
  "error" : "Permission denied."
}

1 个答案:

答案 0 :(得分:1)

呃,我找到了无证件回答here。目前您还需要此范围:

https://www.googleapis.com/auth/userinfo.email