当前位置: 首页 > 知识库问答 >
问题:

如何将github OAuth数据发送到客户端?

令狐建修
2023-03-14

我需要实现一个github授权,然后将接收到的数据(JSON)发送到客户端。

我找到了这篇教程http://shiya.io/how-to-do-3-legged-oauth-with-github-a-general-guide-by-example-with-node-js/

在该教程中,开发人员向我们展示了如下内容:“/”->“/login”->“/redirect”->“/user”(此处为数据)

但我需要:“/”->“/登录”->“/重定向”->“/”(此处为数据)

因为客户端应该使用简单的SPA(react)。

我现在拥有的:


    require('dotenv').config();
    const express = require('express');
    const app = express();
    const session = require('express-session');
    const request = require('request');
    const qs = require('querystring');
    const url = require('url');
    const randomString = require('randomstring');
    const csrfString = randomString.generate();

    const port = process.env.PORT || 8080;
    const redirect_uri = process.env.HOST + '/redirect';

    app.use(express.static('views'));

    app.use(
      session({
        secret: randomString.generate(),
        cookie: { maxAge: 60000 },
        resave: false,
        saveUninitialized: false
      })
    );

    app.get('/', (req, res, next) => {
      res.sendFile(__dirname + '/index.html');
      if (req.session.access_token) {
        request.get(
          {
            url: 'https://api.github.com/user',
            headers: {
              Authorization: 'token ' + req.session.access_token,
              'User-Agent': 'Login-App'
            }
          },
          (error, response, body) => {
            res.send(body);
          }
        );
      }
    });

    app.listen(port, () => {
      console.log('Server listening at port ' + port);
    });

    app.get('/login', (req, res, next) => {
    req.session.csrf_string = randomString.generate();
    const githubAuthUrl =
      'https://github.com/login/oauth/authorize?' +
      qs.stringify({
        client_id: process.env.CLIENT_ID,
        redirect_uri: redirect_uri,
        state: req.session.csrf_string,
        scope: 'user:email'
      });
    res.redirect(githubAuthUrl);
    });

    app.all('/redirect', (req, res) => {
      console.log('Request sent by GitHub: ');
      console.log(req.query);

      const code = req.query.code;
      const returnedState = req.query.state;

      if (req.session.csrf_string === returnedState) {
        request.post(
          {
            url:
              'https://github.com/login/oauth/access_token?' +
              qs.stringify({
                client_id: process.env.CLIENT_ID,
                client_secret: process.env.CLIENT_SECRET,
                code: code,
                redirect_uri: redirect_uri,
                state: req.session.csrf_string
              })
          },
          (error, response, body) => {
            console.log('Your Access Token: ');
            console.log(qs.parse(body));
            req.session.access_token = qs.parse(body).access_token;

            res.redirect('/');
          }
        );
      } else {
        res.redirect('/');
      }
      console.log(redirect_uri);
    });

在这一时刻res.send(身体);抛出错误


    app.get('/', (req, res, next) => {
      res.sendFile(__dirname + '/index.html');
      if (req.session.access_token) {
        request.get(
          {
            url: 'https://api.github.com/user',
            headers: {
              Authorization: 'token ' + req.session.access_token,
              'User-Agent': 'Login-App'
            }
          },
          (error, response, body) => {
            res.send(body);
          }
        );
      }
    });

错误:

    throw new ERR_HTTP_HEADERS_SENT('set');
    ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

它的发生是因为我试图为一次又一次的渲染设置数据。

所以,我的问题是:

如何将数据发送到客户端以及如何在客户端获取数据?

共有1个答案

谭玄天
2023-03-14

HTTP使用的循环要求每个请求有一个响应。当客户端发送请求时,服务器应该只向客户端发送一个响应。

您正在为一个请求发送两个响应res.sendFile()res.send(),因此需要对代码进行如下更改,

app.get('/', (req, res, next) => {
    if (req.session.access_token) {
        request.get({
            url: 'https://api.github.com/user',
            headers: { Authorization: 'token ' + req.session.access_token, 'User-Agent': 'Login-App' }
        }, (error, response, body) => { res.send(body); }
        );
    } else {
        res.sendFile(__dirname + '/index.html');
    }
});
 类似资料:
  • 问题内容: 我正在使用node制作电子邮件客户端。我想在收到任何新电子邮件后立即更新浏览器窗口。我已经使用mail- listener2在服务器端获取电子邮件了。我想将数据推送到客户端。我怎么做? 问题答案: 看一下使用 websocket 将数据实时推送到客户端(浏览器)。我建议使用http://socket.io。他们那里有一些非常棒的演示,展示了您将如何做这样的事情。 您的服务器将发送名为的

  • 问题内容: 如标题所示,我需要将一些数据(从数据库中获取)放入Excel工作表中,然后将其发送到客户端,以便用户可以保存,打开或取消操作。 我看到了一些与此有关的文章,最近的是:如何让用户下载文件?(Java,MVC,Excel,POI)。参考史蒂文斯提供的链接,我尝试了以下代码: 首先这里没有定义。其次,我无法正确理解代码的工作方式。 我还找到了此链接:http : //www.roseindi

  • 我有一个下一个js web应用程序与Express。我想把数据发布到这个网页上,在我的服务器上获取它,然后把它传递到我的下一个js页面。我是next js和Express的新手。以下是我的server.js代码:- 当我使用get request时,我可以使用return app.render(req,res,'/posts',{name:“pritam”})将数据从服务器发送到客户端,但当我尝试

  • 我正在Unity中制作一个游戏,我试图将数据从客户端发送到服务器并返回到客户端(试图保存实例),但当我收到数据并尝试将数据发送回客户端时,它表示udp客户端未连接。 它成功地将数据从我的Unity客户端发送到服务器,但一旦它到达那里,套接字就会断开连接,我就无法返回任何内容。正如你所看到的,我试图设置一些多播选项,但它似乎不能正常工作。 客户: 服务器: 因此,服务器中UdpClient的实例会保

  • 问题内容: 您好,我一直在尝试将文件从node.js发送到客户端。 我的代码有效,但是当客户端转到指定的url()时,它将流式传输文件。 从Google Chrome浏览器访问该文件可使文件(.mp3)在播放器中播放。 我的目标是让客户的浏览器下载文件,然后问客户他想在哪里存储文件,而不是在网站上流式传输。 问题答案: 您需要设置一些标题标志。 用下载代替流媒体;