Pab*_*les 0 google-api google-cloud-print google-oauth reactjs
我正在尝试使用Google Cloud Print(GCP)API,但无法使其正常运行。也许我对工作流程的理解不正确,因为这是我第一次使用Google 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)
Run Code Online (Sandbox Code Playgroud)
获取信息打印机的动作或功能:
说明:
我正在传递参数printerid以获取有关该打印机的信息。
在授权中,我正在使用,OAuth ...因为在文档中说(第二段)。:https://developers.google.com/cloud-print/docs/appInterfaces
接下来的两个标题是我写的,因为我尝试使用以下解决方案:
码:
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 }
Run Code Online (Sandbox Code Playgroud)
错误:
毕竟在我解释完之后,我得到了下一个错误:
需要用户凭证
错误403
注意:
根据以下建议,我正在使用CORS插件:
因为最初,我有cors错误。
任何建议或建议都将非常有用,谢谢。
我已经解决了我的问题,我的主要问题User Credential required是因为我使用了不正确的访问令牌,这是因为我没有正确获取访问令牌。
我将解释整个解决方案,因为此API的代码示例很少。
解决方案:
所描述的步骤是确定的,直到第四步,我使用外部组件react-google-login尝试获取访问令牌,而使用googleapis模块:Link Github googleapis
同样为了避免CORS问题(并且不使用CORS chrome插件),我在服务器端将请求写入了Google API。(NODEJS)
当我尝试生成一个弹出窗口以授予打印机权限时(在CORS方面的问题),我在前端也遇到了问题,我的解决方案是使用此非常简单的模块进行身份验证:Link Github oauth-open
总体方案:
说明:
知道我已经在问题帖中描述了所有数据(直到第三步)。
认证方式:
获取URL并将其用于用户的下一步可以进行身份验证。就像我之前说过的,我oauth-open在前端使用模块来生成弹出窗口,只有该模块需要URL。为了在后端获取URL,我使用了endpoint /googleurl,在这里我使用generateAuthUrl了模块的方法googleapis来生成URL。
之后,在前台,我得到了authentication_code(返回的模块oauth-open),我把它给我的终点/googletoken,在这里我处理authentication_code生成access token,refresh token并expiration date用该方法getToken的模块googleapis。最后,这些数据存储在数据库中。
打印:
对于打印,从前端开始,我将需要发送的数据发送到打印机。我用了我的终点/print
在后端端点中,我的逻辑是下一个:
从数据库中恢复令牌和到期日期,并用到期日期检查令牌是否已过期,如果令牌已过期,则获取另一个令牌,并用access token新令牌替换旧令牌,也用新令牌替换expiration date,以仅获取此新数据是refreshAccessToken对模块方法的必要调用googleapis。注意:刷新令牌永不过期。
更新访问令牌后,使用它通过Google route(.../submit)将数据发送到打印机
码:
路由获取URL认证。
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 }
});
});
Run Code Online (Sandbox Code Playgroud)
要使用身份验证代码获取令牌并将其保存在数据库中。
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'
});
})
}
});
});
Run Code Online (Sandbox Code Playgroud)
打印
const axios = require('axios');
const moment = require('moment');
router.post('/print',async (req, res) => {
const tickeProperties = {
'version': '1.0',
'print': {
'vendor_ticket_item': [],
'color': { 'type': 'STANDARD_MONOCHROME' },
'copies': { 'copies': 1 }
}
};
const accessToken = await getTokenGoogleUpdated();
axios.get(
'https://www.google.com/cloudprint/submit',
{
params: {
printerid : printerID, // Replace by your printer ID
title: 'title printer',
ticket: tickeProperties,
content : 'print this text of example!!!',
contentType: 'text/plain'
},
headers: {
'Authorization': 'Bearer ' + accessToken
}
}
)
.then(response => {
return res.status(200).send({
result: response.data
});
})
}
);
async function getTokenGoogleUpdated() {
return await Setting.find({})
.then(async setting => {
const refreshTokenGoogle = setting[0].refreshTokenGoogle;
const expirationTokenGoogle = setting[0].expirationTokenGoogle;
const tokenGoogle = setting[0].tokenGoogle;
const dateToday = new Date();
// 1 minute forward to avoid exact time
const dateTodayPlus1Minute = moment(dateToday).add(1, 'm').toDate();
const dateExpiration = new Date(expirationTokenGoogle);
// Case date expiration, get new token
if (dateExpiration < dateTodayPlus1Minute) {
console.log('Updating access token');
oauth2Client.credentials['refresh_token'] = refreshTokenGoogle;
return await oauth2Client.refreshAccessToken( async function(err, tokens) {
// Save new token and new expiration
setting[0].expirationTokenGoogle = tokens.expiry_date;
setting[0].tokenGoogle = tokens.access_token;
await setting[0].save();
return tokens.access_token;
});
} else {
console.log('Using old access token');
return tokenGoogle;
}
})
.catch(err => {
console.log(err);
});
}
Run Code Online (Sandbox Code Playgroud)
希望它对您有帮助,如果您不想使用Google Cloud Print浪费很多时间。
| 归档时间: |
|
| 查看次数: |
2534 次 |
| 最近记录: |