0

Lets take a system where a jwt token is saved to local storage upon login and now we check for the token existence to allow a user access to a protected route.

We're using react-router-redux and bundling everything with webpack and our code is in the client/src folder as apposed to the server folder.

So the protected route with our auth check would look something like the following (let's say we send our routes only on demand) :

import { push } from 'react-router-redux'

    function requireAuth(store) {
        const check = localStorage.jwt
        check ? store.dispatch(push('/dashboard')) : store.dispatch(push('/'))
    }

    export default (store) => ({
      path: 'dashboard',
      onEnter: requireAuth(store),
      getComponent (nextState, cb) {
        require.ensure([], (require) => {
          const Dashboard = require('./containers/DashboardContainer').default
          cb(null, Dashboard)
        }, 'dashboard')
      }
    }) 

And for completion our index routes file:

    import Login from './login'
    import Dashboard from './Dashboard'
    import Logout from './Logout'

    export const createRoutes = (store) => ({
      path: '/',
      indexRoute: Login,
      childRoutes: [
        Dashboard(store), //Our protected route
        Logout(store)
      ]
    })

    export default createRoutes

Putting a side man in the middle attacks and the inherint problems with the nature of javascript crypto methos as discussed here: SPA best practices for authentication and session management

I would like to focus on the above illustrated method of a function placed on the onEnter to allow access:

If I understand correctly the above example is bundled and sent to the client, Now I might be wrong and the route definitions aren't actually being sent in the bundle. So I guess the question is: does a user has access or can see our above route definitions by default - if so how do we prevent it?

Also in regards to our auth check in the example, which I've seen used and simply redirects if a token is not present in the local storage, is that really sufficient prevention?

Comparing the above example to using a high order function to wrap our protected component with, so we can preform auth checks in the life cycle methods WillMount and WillRecieveProps as you can see here for example.

I would think that both approaches would suffer from being exposed to the client. Am I right?

What other caveats am I missing regarding each approach?

Community
  • 1
  • 1
S. Schenk
  • 1,960
  • 4
  • 25
  • 46

1 Answers1

1

In my opinion you shouldn't store you JWT token in localStorage, instead you should keep it as a cookie with httpOnly and secure flags as true. So that your client script can't get your JWT token. Also man in the middle attacks are not possible since you are sending your cookie on https only.

You could have a api endpoint which checks if the client has JWT and if it is valid. So that you can do your redirects on onEnter function wherever you need.

EDIT

If I understand correctly the above example is bundled and sent to the client, Now I might be wrong and the route definitions aren't actually being sent in the bundle. So I guess the question is: does a user has access or can see our above route definitions by default - if so how do we prevent it?

Yes your whole application is being sent to client with your all client code, so anyone can see what you have written if they want to.

Also in regards to our auth check in the example, which I've seen used and simply redirects if a token is not present in the local storage, is that really sufficient prevention?

Not really, if you have a invalid token, you redirect your user to page and if this page does some fetching from server, you will get 401 error and you will have to check 401 errors so that you can redirect user to login. Which doesn't seem efficient or clear.

Comparing the above example to using a high order function to wrap our protected component with, so we can preform auth checks in the life cycle methods WillMount and WillRecieveProps as you can see here for example.

All of them are being exposed to client except httpOnly flag true cookie.

Hope it helps.

FurkanO
  • 7,100
  • 5
  • 25
  • 36
  • I think most articles support the idea that using cookies is more secure than localstorage, but in cases of using localstorage (I'm dealing with such use case in a very small app right now) I would like to know about the two methods I've illustrated. – S. Schenk Sep 19 '16 at 14:10
  • I'm checking the actual tokens server side against the db, but on the client side I haven't found a good solution to scenarios where a user have a bad token or fake one in localstorage and they now try to access a protected api route and make a server call. It's quite frustrating since cookies can't always be used. – S. Schenk Sep 22 '16 at 10:19