我尝试使用Google云打印(GCP)API,但我无法使其正常运行。 也许我已经理解了工作流程的不好,因为这是我第一次使用谷歌API,请帮助我了解如何使其工作。
初步考虑因素:
我到底想要什么:
要进行第一次测试,我希望获得有关打印机的所有信息。
我做了什么:
我选择了应用程序类型:Web,并且还配置了对源和重定向到本地主机的限制。
在https://www.google.com/cloudprint手动,我添加了我的打印机,我做了一个测试打印PDF并且没问题。
我在reactJS中创建了一个项目,以获取我已添加的打印机信息。
组件:
说明:
我使用组件react-google-login
轻松获取用户accessToken:https://github.com/anthonyjgrove/react-google-login
此组件仅获取访问令牌并将其保存在localStorage中,名为googleToken
的变量中,并绘制一个按钮来调用函数以获取有关打印机的信息。
代码:的
import React, { Component } from 'react'
import GoogleLogin from 'react-google-login';
import { connect } from 'react-redux'
import { getPrinters } from '../actions/settings'
class Setting extends Component {
responseGoogle(response) {
const accessToken = response.accessToken
localStorage.setItem('googleToken', accessToken)
}
render() {
return (
<div>
<GoogleLogin
clientId="CLIENT_ID_REMOVED_INTENTIONALLY.apps.googleusercontent.com"
buttonText="Login"
onSuccess={this.responseGoogle}
onFailure={this.responseGoogle}
/>
<button
onClick = {() => {
this.props.getPrinters()
}}
>test printer</button>
</div>
)
}
}
const mapStateToProps = state => {
return {
state: state
}
}
const mapDispatchToProps = dispatch => {
return {
getPrinters() {
dispatch(getPrinters())
}
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Setting)
获取信息打印机的操作或功能:
说明:
我传递参数printerid
以获取有关该打印机的信息。
在授权中,我使用OAuth ...
,因为在文档中说(第二段):https://developers.google.com/cloud-print/docs/appInterfaces
我编写的下两个标题是因为我尝试了解决方案:
Google Cloud Print API: User credentials required
Google Cloud Print User credentials required
代码:的
import axios from 'axios'
axios.defaults.headers.common['Authorization'] = 'OAuth ' + localStorage.getItem('googleToken')
axios.defaults.headers.common['scope'] = 'https://www.googleapis.com/auth/cloudprint'
axios.defaults.headers.common['X-CloudPrint-Proxy'] = 'printingTest'
const getPrinters = () => {
return () => {
return axios.get('https://www.google.com/cloudprint/printer'
, {
params: {
printeid: 'PRINTER_ID_REMOVED_INTENTIONALLY'
}
}
)
.then(response => {
console.log('response of google cloud print')
console.log(response)
})
}
}
export { getPrinters }
错误:
之前解释过后,我收到了下一个错误:
需要用户凭据
错误403
注意:
我推荐使用CORS插件:
Chrome extensions for silent print?
因为最初我有错误。
任何建议或建议都非常有用,谢谢。
答案 0 :(得分:3)
我已经解决了我的问题,我关于User Credential required
的主要问题是因为我使用了错误的访问令牌而这是因为我错误地获取了访问令牌。
我将解释我的整个解决方案,因为此API的代码示例很少。
<强>解决方案:强>
所描述的步骤一直很好,直到我使用外部组件react-google-login
试图获取访问令牌的第四步,而不是我使用googleapis
模块:Link Github googleapis < / p>
另外为了避免CORS问题(并且不使用CORS chrome插件)我在服务器端向Google API写了请求。(NODEJS)
当我尝试生成弹出窗口以获得打印机权限(CORS问题)时,我在前端也遇到了问题,我的解决方案是使用这个非常简单的模块进行身份验证:Link Github oauth-open < / p>
一般方案:
说明:
知道我在问题帖子中描述了所有数据(直到第三步)。
验证
获取URL并将其用于用户的下一步可以进行身份验证。
正如我之前所说,我在前端使用模块oauth-open
来生成弹出窗口,只有这个模块需要URL。要在后端获取网址,我使用了端点/googleurl
,在这里我使用了模块generateAuthUrl
的方法googleapis
来生成网址。
之后在前端,我得到authentication_code
(返回模块oauth-open
),我将它发送到我的端点/googletoken
,在这里我处理{{ 1}}使用模块authentication_code
的方法access token
生成refresh token
,expiration date
和getToken
。最后,这些数据存储在数据库中。
打印:
对于打印,从前端开始,我将需要发送的数据发送到打印机。我使用了我的端点googleapis
在后端端点,我的逻辑是下一个:
从数据库中恢复令牌和过期日期,并在过期日期检查令牌是否已过期,如果已过期,则获取另一个令牌并将旧/print
替换为新令牌,同时替换为新access token
,仅获取此新数据是对模块expiration date
的方法refreshAccessToken
的必要调用。注意:刷新令牌永不过期。
更新访问令牌后,使用它通过Google路线(googleapis
)
<强>代码:强>
路由获取URL身份验证。
.../submit
使用身份验证代码获取令牌并将其保存在数据库中。
const express = require('express');
const google = require('googleapis');
const router = express.Router();
var OAuth2 = google.auth.OAuth2;
const redirect_url = 'http://localhost:3001/setting'; //Your redirect URL
var oauth2Client = new OAuth2(
'CLIENT ID', //Replace it with your client id
'CLIEND SECRET', //Replace it with your client secret
redirect_url
);
var url = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: 'https://www.googleapis.com/auth/cloudprint'
});
router.get('/googleurl', (req, res) => {
return res.status(200).send({
result: { googleURLToken: url }
});
});
打印
const Setting = require('../models/setting'); // My model(Mongoose)
router.post('/googletoken', (req, res) => {
oauth2Client.getToken(req.body.code, function (err, tokens) {
oauth2Client.credentials = tokens;
// If refresh token exits save it
// because the refresh token it returned only 1 time! IMPORTANT
if (tokens.hasOwnProperty('refresh_token')) {
let setting = new Setting();
setting.refreshTokenGoogle = tokens.refresh_token;
setting.expirationTokenGoogle = tokens.expiry_date;
setting.tokenGoogle = tokens.access_token;
setting.save()
.then((settingCreated) => {
return res.status(200).send({
message: 'OK'
});
})
}
});
});
我希望如果您想使用Google云打印,不要像我一样浪费大量时间,这会对您有所帮助。
答案 1 :(得分:0)
其中一个重要部分是范围https://www.googleapis.com/auth/cloudprint
,这个范围并不明显,我花了一天的时间才弄清楚。