我正在尝试从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 =“用户未获得授权。”
但是,似乎它确实识别出正确的用户,因为响应的用户字段确实是[“{{MY_APP_ID}} @ appspot.gserviceaccount.com”]。
我做错了什么?有没有办法让App Engine应用程序使用应用程序自己的权限打印到Google Cloud Print?
答案 0 :(得分: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();
}
}
答案 1 :(得分:0)
TL; DR- https://stackoverflow.com/a/19951913/929444
长版 -
当您授予某人使用Google云打印打印机的权限时,Google会通过电子邮件将其发送给他们批准。当然,谷歌的用户界面并没有以任何方式表明它。由于AppEngine应用程序用户无法按下电子邮件链接,因此实际上没有直接的方式来执行我想要的操作。
如上面的链接所示,解决方法是创建一个包含AppEngine应用和其他常规用户的Google网上论坛。每当有人添加该组时,常规用户都会批准,并且该应用程序将作为该组的一部分隐式授予权限。
答案 2 :(得分:0)
创建一个Google网上论坛。通过直接邀请添加成员:
您的gmail帐户(gmail电子邮件地址)
提供访问令牌的Google服务帐户(服务帐户电子邮件地址)
然后执行以下步骤:
选择您的打印机,然后单击“共享”选项卡。在邀请人员下添加以下成员:
-google服务帐户的电子邮件地址
-google网上论坛的电子邮件地址(例如xyz@googlegroups.com)
然后尝试调用GCP API。它将完美运行。