I need to implement a github authorization and later send received data (JSON) to the client.
I found this tutorial http://shiya.io/how-to-do-3-legged-oauth-with-github-a-general-guide-by-example-with-node-js/
In that tutorial developer shows us this way: "/" -> "/login" -> "/redirect" -> "/user"(data here)
But i need: "/" -> "/login" -> "/redirect" -> "/"(data here)
Because the client is supposed to uses simple SPA(react).
What i have now:
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); });
In this moment res.send(body); throws an error
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); } ); } });
Error:
throw new ERR_HTTP_HEADERS_SENT('set'); ^ Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
It happens because I trying to set data for rendering after rendering.
So, my question:
How i can to send data to a client and how get it on client side?