错误:Google Cloud Print API中

时间:2017-11-27 19:25:37

标签: reactjs google-api google-oauth google-cloud-print

我尝试使用Google云打印(GCP)API,但我无法使其正常运行。 也许我已经理解了工作流程的不好,因为这是我第一次使用谷歌API,请帮助我了解如何使其工作。

初步考虑因素:

  • 我试图在reactJS中实现它,但它无动于衷,因为使GCP工作的逻辑独立于技术。然后你也可以帮我理解工作流程。

我到底想要什么:

要进行第一次测试,我希望获得有关打印机的所有信息。

我做了什么:

  1. 我在:https://console.developers.google.com
  2. 中创建了一个项目
  3. 在创建的项目中,我创建了一个凭证:
    • 创建凭据 - > OAuth客户端ID
  4. 我选择了应用程序类型:Web,并且还配置了对源和重定向到本地主机的限制。

    1. https://www.google.com/cloudprint手动,我添加了我的打印机,我做了一个测试打印PDF并且没问题。

    2. 我在reactJS中创建了一个项目,以获取我已添加的打印机信息。

    3. 组件:

      说明:

      • 我使用组件react-google-login轻松获取用户accessToken:https://github.com/anthonyjgrove/react-google-login

      • 此组件仅获取访问令牌并将其保存在localStorage中,名为googleToken的变量中,并绘制一个按钮来调用函数以获取有关打印机的信息。

        < / LI>

      代码:

      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)
      

      获取信息打印机的操作或功能:

      说明:

      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?

      因为最初我有错误。

      任何建议或建议都非常有用,谢谢。

2 个答案:

答案 0 :(得分:3)

我已经解决了我的问题,我关于User Credential required的主要问题是因为我使用了错误的访问令牌而这是因为我错误地获取了访问令牌。

我将解释我的整个解决方案,因为此API的代码示例很少。

<强>解决方案:

  1. 所描述的步骤一直很好,直到我使用外部组件react-google-login试图获取访问令牌的第四步,而不是我使用googleapis模块:Link Github googleapis < / p>

  2. 另外为了避免CORS问题(并且不使用CORS chrome插件)我在服务器端向Google API写了请求。(NODEJS)

  3. 当我尝试生成弹出窗口以获得打印机权限(CORS问题)时,我在前端也遇到了问题,我的解决方案是使用这个非常简单的模块进行身份验证:Link Github oauth-open < / p>

  4. 一般方案:

    enter image description here

    说明:

    知道我在问题帖子中描述了所有数据(直到第三步)。

    验证

    • 获取URL并将其用于用户的下一步可以进行身份​​验证。 正如我之前所说,我在前端使用模块oauth-open来生成弹出窗口,只有这个模块需要URL。要在后端获取网址,我使用了端点/googleurl,在这里我使用了模块generateAuthUrl的方法googleapis来生成网址。

    • 之后在前端,我得到authentication_code(返回模块oauth-open),我将它发送到我的端点/googletoken,在这里我处理{{ 1}}使用模块authentication_code的方法access token生成refresh tokenexpiration dategetToken。最后,这些数据存储在数据库中。

    打印:

    • 对于打印,从前端开始,我将需要发送的数据发送到打印机。我使用了我的端点googleapis

    • 在后端端点,我的逻辑是下一个:

    从数据库中恢复令牌和过期日期,并在过期日期检查令牌是否已过期,如果已过期,则获取另一个令牌并将旧/print替换为新令牌,同时替换为新access token,仅获取此新数据是对模块expiration date的方法refreshAccessToken的必要调用。注意:刷新令牌永不过期。

    更新访问令牌后,使用它通过Google路线(googleapis

    将数据发送到打印机

    <强>代码:

    • 所有下一个代码只有1个文件
    • 为了更好地理解,删除了一些数据,如验证,静态变量,错误处理程序等。

    路由获取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,这个范围并不明显,我花了一天的时间才弄清楚。