4

I am building a web application with React and react-router and I would like to protect some routes of my React application with an existing external access management infrastructure (OpenAM).

I would like to protect the http://web.example.com:8080/myapp/#/user-profile url which means that only logged users can have access to this route.

I have some other routes which are public and any user can open them, for example http://web.example.com:8080/myapp/#/welcome.

The Access Management protects urls and if a user wants to open a protected url then a login form is shown by Access Management and after a successful login the original requested url will be displayed.

The problem here is that react-router adds the routing info after the '#' character and the above mentioned two different urls are same from the access manager point of view because they refer to the same web resource (/myapp). The different between these two urls appear after the '#' character.

I need to have real urls without '#' chars like this:

Is there any way to use real url mappings with React? Do you guys have any idea or workaround how to use real url routes with react?

Thanks.

UPDATE: This is my code. The urls in the web browser look nice but I get a "about did not match any routes" error. Requested url: http://web.example.com:8080/myapp/about

import {Router, Route, IndexRoute, useRouterHistory} from 'react-router';
import {createHistory} from 'history';    

const browserHistory = useRouterHistory(createHistory) ({
   basename: '/myapp/'
});

ReactDOM.render(
   <Router history={browserHistory}>
      <Route path="/" component={MainLayout}>
         <IndexRoute component={Home} />
         <Route path="about" component={About} />
      </Route>
   </Router>
)
zappee
  • 20,148
  • 14
  • 73
  • 129
  • Well `react-router` supports using browser history like this, but you have to configure your server to serve the correct resources. – Aaron Beall Jul 11 '16 at 19:41
  • Can you show us the relevant wire-up of your routes? `react-router` supports `onEnter` props on its routes. You could write a function that gets invoked every time you hit it. – Mario Tacke Jul 11 '16 at 21:10
  • I added history={browserHistory} to my Router tag and I the # char gone. It looks nice. Now I have another issue. The root url is http://web.example.com:8080/myapp and the welcome content is linked to http://web.example.com:8080/welcome instead of http://web.example.com:8080/myapp/welcome. Brrr... – zappee Jul 11 '16 at 22:10

1 Answers1

0

You could use browserHistory, as suggested in the comments, to get rid of the #-sign. If you want the root of your react-application to be /myapp/ instead of / you can try:

import {Router, Route, useRouterHistory} from 'react-router';
import {createHistory} from 'history';    

const browserHistory = useRouterHistory(createHistory)({basename: '/myapp/'});

ReactDOM.render(
  <Router history={browserHistory}>
    ...
  </Router>
)
Chris
  • 57,622
  • 19
  • 111
  • 137
  • Thanks for the help. Now the url what I can see in the browser looks nice. When i click on the home Link then web.example.com:8080/myapp appears. When I click on the 'About' link then I can see web.example.com:8080/myapp/about in the browser. But something wrong with the mapping because an "/about did not match any routes" error appears on the browser's console. I have added my current routing code to the original post. What is wrong with my mapping? Thx. – zappee Jul 12 '16 at 16:37
  • @zappee, hmm weird. Try putting the route as `` instead. Does that work? – Chris Jul 12 '16 at 17:04
  • Unfortunately I can not close this topic. The routing logic works, I can see the proper content if I click on the Link and the the url looks so pretty. But I need to go back to the original question :( I think that the url what appears in the browser is just a fake url. When I want to reload it ( http://web.example.com:8080/myapp/about) then I get a HTTP 404. So react-router just overwrite the browser's url as a "string". – zappee Jul 12 '16 at 18:29
  • And the browser does NOT do anything with this new, modified url and browser does NOT load this fake url when I click on the link. JavaScript does some magic at the background. And because this is just a fake url and browser does not send any request when I click on the link my URL based security does not work. User can have access to any protected url :((( Do you know any workaround to solve my original question? – zappee Jul 12 '16 at 18:35
  • 1
    `react-router` is meant not to make any requests to the server. Those are indeed "fake" urls. You need to configure your application appropriately. For example, if you are requesting `myapp/about`, the server must **always** handle as if you requested `myapp/`. This really depends on how your backend works, but here's a [good video](https://www.youtube.com/watch?v=cdUyEou0LHg) to get your started. – Chris Jul 12 '16 at 18:49
  • Thx for the video!!! That was very useful. Only one solution come up off the top of me head. I need to use two real html files. One for the public routes and contents and another for the public + protected contents together. And if user click on a protected link then react-router needs to make somehow a redirect to the /myapp/private.html file. It is seems as a stupid solution but i have no another idea at the moment :(( Can I put two webpack config file in the same folder to create two different boundle.js files? For example public-boundle.js and protected-boundle.js. – zappee Jul 12 '16 at 19:36
  • Getting a bit too complicated without knowing your project too well. You might be able to but not sure if that's a good approach. – Chris Jul 12 '16 at 19:38
  • Or maybe I need to use another framework on the UI side, like angular? I really do not know. – zappee Jul 12 '16 at 19:39
  • Keep searching friend. Perhaps post a new question and add more details. It's hard (for me at least) to understand 100% how your whole app looks like and what the problem is. Good luck. – Chris Jul 12 '16 at 19:41
  • 1st step towards the solution: add this to the web.xm file: 404/index.html With this trick the fake urls become reals on Apache-Tomcat :) – zappee Jul 12 '16 at 20:12
  • 1
    final step: use about instead of about That way the browser will send a request so Access Management can catch the request and check the login status of the user. That is it :) – zappee Jul 13 '16 at 09:22