1

我正在尝试从 App Engine 应用 (Java) 向 Google Cloud Print 提交新的打印作业。

在打印机的 Google 云打印设置中,我将“可以打印”权限设置为 {{MY_APP_ID}}@appspot.gserviceaccount.com

然后,从 App Engine 应用程序运行以下代码 -

AppIdentityCredential credential = new AppIdentityCredential(
   Arrays.asList("https://www.googleapis.com/auth/cloudprint"));
HttpRequestFactory requestFactory =
   new UrlFetchTransport().createRequestFactory(credential);

Map<String, String> params = new LinkedHashMap<String, String>();
params.put("printerid", "{{PRINTER_ID}}");
params.put("title", "Title");
params.put("ticket", "{\"version\":\"1.0\", \"print\":{}}");
params.put("content", "<!DOCTYPE html>\n<html>\n<body>\nHello world!\n</body>\n</html>");
params.put("contentType", "text/html");

HttpRequest httpRequest = requestFactory.buildPostRequest(
   new GenericUrl("https://www.google.com/cloudprint/submit"),
   new UrlEncodedContent(params));

HttpResponse httpResponse = httpRequest.execute();
try {
    System.out.println(httpResponse.parseAsString());
} finally {
    httpResponse.ignore();
}

Google Cloud Print 的 API 返回成功=false 和 message="User is not authorized." 的响应。

但是,它似乎确实识别出正确的用户,因为响应的用户字段确实是 ["{{MY_APP_ID}}@appspot.gserviceaccount.com"]。

我究竟做错了什么?有没有办法让 App Engine 应用程序使用应用程序自己的权限打印到 Google 云打印?

4

3 回答 3

2

上面的示例代码不会在抛出未经授权的错误消息的标头中发送身份验证字符串 - 对 Oauth 2 的以下修改和更新适用于与服务帐户共享的打印机:

    private static final String APPLICATION_NAME = "my-cloud-print";
    private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
    private static final String KEY_FILE_LOCATION = "file.p12";
    private static final String SERVICE_ACCOUNT_EMAIL = "12345@developer.gserviceaccount.com";

    public static void main( String args[] ){

        try{

            HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();

            //service login
            GoogleCredential credential = new GoogleCredential.Builder()
                .setTransport(httpTransport)
                .setJsonFactory(JSON_FACTORY)
                .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
                .setServiceAccountPrivateKeyFromP12File(new File(KEY_FILE_LOCATION))
                .setServiceAccountScopes(Collections.singleton("https://www.googleapis.com/auth/cloudprint"))
                .build();

            //update to fetch token
            credential.refreshToken();
            String accessToken = credential.getAccessToken();

            Map<String, String> params = new LinkedHashMap<String, String>();
            params.put("printerid", "0000000-f960-1d6b-077f-750e5b45fbdd");
            params.put("title", "Title");
            params.put("ticket", "{\"version\":\"1.0\", \"print\":{}}");
            params.put("content", "<!DOCTYPE html>\n<html>\n<body>\nHello world!\n</body>\n</html>");
            params.put("contentType", "text/html");

            HttpRequestFactory requestFactory = httpTransport.createRequestFactory();
            HttpRequest httpRequest = requestFactory.buildPostRequest(
               new GenericUrl("https://www.google.com/cloudprint/submit"),
               new UrlEncodedContent(params)
            );

            //important bit - must send the auth token to print service
            //after you process the invitation from the share 
            //see http://stackoverflow.com/questions/19767752
            httpRequest.getHeaders().set("Authorization", Arrays.asList( ("Bearer " + accessToken).split(",") ));

            HttpResponse httpResponse = httpRequest.execute();
            try {
                System.out.println(httpResponse.parseAsString());
            } finally {
                httpResponse.ignore();
            }
        } catch( Exception ex ){
            ex.printStackTrace();
        }

    }
于 2016-12-06T04:30:59.247 回答
0

TL;DR- https://stackoverflow.com/a/19951913/929444

长版——

当您授予某人使用 Google 云打印打印机的权限时,Google 会通过电子邮件向他们发送批准。当然,Google 的 UI 并没有以任何方式表明它。由于 AppEngine 应用程序用户无法按下电子邮件链接,因此确实没有一种直接的方式来做我想做的事。

如上面链接中所建议的,一种解决方法是创建一个包含 AppEngine 应用程序和另一个普通用户的 Google 组。每当有人添加组时,常规用户都会批准,并且应用程序将被隐式授予权限作为组的一部分。

于 2014-04-20T14:20:14.583 回答
0

创建一个谷歌组。通过直接邀请添加成员:

  1. 您的 gmail 帐户(gmail 电子邮件地址)

  2. 提供访问令牌的 Google 服务帐户(服务帐户电子邮件地址)

然后按照以下步骤操作:

  1. 访问 google.com/cloudprint
  2. 选择您的打印机,然后单击共享选项卡。在邀请人下添加以下成员:

    -google 服务帐户电子邮件地址

    -google 群组电子邮件地址(例如,xyz@googlegroups.com)

然后尝试调用 GCP API。它将完美地工作。

于 2019-03-28T10:25:07.097 回答