2

I have read a lot of answers but couldn't able to find anything satisfactory. The user roles in the application depend on the information I will receive in headers. I have already tried this:

var req = new XMLHttpRequest(); req.open('GET', document.location,false); req.send(null); 
var headers = req.getAllResponseHeaders().toLowerCase(); alert(headers);

But i think i generates a new request and by then the URL changes so the headers are not the same. If there is any other option to get the headers please guide me with the same

Edit 1 (This will clarify the question a little more):

  • The user would click on my application(Let's say application1) link via another application (Let's say application2).
  • Then the applicaion2 will send the HTTP/HTTPs headers in requests forwarded by the reverse proxy, which will contain user role and some more information.
  • In the headers I will receive user roles.
  • Depending on the role the kind of access would be determined and given to user
3
  • 1
    the request headers will obviously be sent by the browser to your server - so, your server can read these request headers ... and can send the info back in the response if you want (and you can write code on the server) Commented Oct 17, 2019 at 5:39
  • Your question is not very clear. However, I suggest you to use github.com/axios/axios for large applications. Commented Oct 17, 2019 at 5:40
  • @Sankalp Chawla, Make sure you mark the answer which helped you to solve the issue as accepted. So, it will help the future visitors. Commented Oct 17, 2019 at 6:38

3 Answers 3

0

As this question/answer clarifies, getting the original response headers for the page is not possible in javascript. But in any case, this is not the way to achieve robust user access control. Rather, you want the server to provide those details to the client, having read and parsed the original request headers.

Sign up to request clarification or add additional context in comments.

Comments

0

If I understand your question correctly, It seems you are trying to get the request headers on initial page load.

At present, there is no API to give you the HTTP response headers for your initial page request. However, you can get and set headers on AJAX requests.

1. Make an ajax request on page load.

So, the easier solution is to simply make an AJAX request to the server on page load. As you are using ReactJS, make the request on componentDidMount

componentDidMount() {
    var req = new XMLHttpRequest();
    req.open('GET', document.location, false);
    req.send(null);
    var headers = req.getAllResponseHeaders().toLowerCase();
    headers = headers.split(/\n|\r|\r\n/g).reduce(function(a, b) {
        if (b.length) {
            var [ key, value ] = b.split(': ');
            a[key] = value;
        }
        return a;
    }, {});
    console.log(headers);
}

Here is the working demo

2. Using web workers.

Another solution I can suggest is to take help of service workers. You can use https://github.com/gmetais/sw-get-headers and implement it in your application.

// Needed because the library uses browserify
var swgetheaders = require('swgetheaders');

// Register the service worker (with some options)
swgetheaders.registerServiceWorker('/swgetheaders-worker.js', {
    debug: true,
    corsExceptions: [
        'code.jquery.com',
        'platform.twitter.com'
    ]
});

swgetheaders.on('plugged', function() {
    console.log('The service worker is now activated and ready to listen to requests');
});

swgetheaders.on('response', function(request, response) {
    console.log('A response just arrived. We have both the request and the response:', request, response);
});

10 Comments

I went through the documentation of web workers but I didn't quite get what is happening. Can you please explain a little how is it working?
Moreover, I found this in the documentation: Please note that the worker will not be available on the first page load, but only after a page change or a reload. This is due to some limitations in Service Workers. . So I guess it defeats the purpose as I explained in my question and I have already tried first option but no luck.
You can use it on initial page load. You just have to register the worker in your top level React componet before you do the authorisation, so that it will be ready with data to authorise the roles. I'm not sure for where you got the information that you mentioned in above comment. Webworkers will be available immediately once you register in your application. And it runs on a separate thread, so it uses Broadcasting mechanism to communicate with the main thread.
Here is the documentation which explains it clearly developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/…
Also you can refer to the service worker which react creates when you create an app using create-react-app github.com/vish25v/react-todo-list/blob/master/src/… And this question have some example stackoverflow.com/questions/47475360/…
|
0

After converting the application to server-side rendering I was able to get the headers with the following script:

import path from 'path'
import fs from 'fs'
import express from 'express'
import React from 'react'
import ReactDOMServer from 'react-dom/server'
import { StaticRouter } from 'react-router-dom';
import App from '../src/App'
import UserContext from '../src/config/UserContext'
import serialize from "serialize-javascript"
const https = process.env.NODE_ENV === "production" ? require("spdy") : require("https")
var privateKey = fs.readFileSync(path.resolve(__dirname, "file.key"), 'utf8');
var certificate = fs.readFileSync(path.resolve(__dirname, "file.cer"), 'utf8');
var credentials = { key: privateKey, cert: certificate };

const tls = require('tls');
tls.DEFAULT_MIN_VERSION = 'TLSv1';

const PORT = anyport
const app = express()
var httpsServer = https.createServer(credentials, app);
const router = express.Router()



const serverRenderer = (req, res) => {
  const context = {};
  //console.log(req.headers);
  var a = 'anything';
  var b = 'anything';
  //console.log(req.headers["variable_name_in_header"]);
  var reqHeaders = req.headers;
  console.log(reqHeaders);
  if ("variable_name_in_header" in reqHeaders) {
   
    //anything

  }
  
  
  const initialState = { a, b };
  //const appString = ReactDOMServer.renderToString(<StaticRouter location={req.url} context={context}><App {...initialState} /></StaticRouter>);

  const appString = ReactDOMServer.renderToString(

    <StaticRouter location={req.url} context={context} basename={'/'}>
      <App {...initialState} />
    </StaticRouter>

  );

  fs.readFile(path.resolve('./build/index.html'), 'utf8', (err, data) => {
    if (err) {
      console.error(err)
      return res.status(500).send('An error occurred')
    }

    return res.send(
      data.replace(
        '</body>',
        `<script>window.__INITIAL_DATA__ = ${serialize(initialState)}</script></body>`
      ).replace(
        '<div id="root"></div>',
        `<div id="root">${appString}</div>`
      )
    )
  })

}

router.use('^/$', serverRenderer)

router.use(
  express.static(path.resolve(__dirname, '..', 'build'), { maxAge: '30d' })
)

// tell the app to use the above rules
app.use(router)

// app.use(express.static('./build'))
httpsServer.listen(PORT, () => {
  console.log(`SSR running on port ${PORT}`);
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.