Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Best place to load existing JWT token #158

Open
james-lukensow opened this issue May 17, 2017 · 3 comments
Open

Best place to load existing JWT token #158

james-lukensow opened this issue May 17, 2017 · 3 comments
Labels

Comments

@james-lukensow
Copy link

james-lukensow commented May 17, 2017

I've been looking at the following example (https://github.com/mjrussell/react-redux-jwt-auth-example/tree/react-router-redux) since it's the closest to my existing setup (react-boilerplate).

For users who refresh the page or come back, I'm curious as to what is the preferred way to load an existing JWT token.

I noticed inside /src/index.js, we're loading the token then calling the action:

let token = localStorage.getItem('token');
if (token !== null) {
    store.dispatch(loginUserSuccess(token));
}

Is this a fairly standard way of loading existing tokens and setting the state.auth?

Lastly, all of the examples I've found seem to following the same approach...

export const requireAuthentication = UserAuthWrapper({
  authSelector: state => state.auth,
  predicate: auth => auth.isAuthenticated,
  redirectAction: push,
  wrapperDisplayName: 'UserIsJWTAuthenticated'
})

My question is, authSelector and predicate, I'm not entirely sure what I should be referencing? Is this the state that my Login action/reducer sets after a successful login?

@james-lukensow
Copy link
Author

james-lukensow commented May 18, 2017

Not sure if I'm doing this correctly or not, but I'm using the following https://github.com/react-boilerplate with redux-auth-wrapper.

The only way I can get the authSelector to work is via the following:

export const UserIsAuthenticated = UserAuthWrapper({
  authSelector: state => state.toJS().global.user,
  wrapperDisplayName: 'UserIsAuthenticated',
  redirectAction: push,
});

I was under the impression, that since react-boilerplate uses immutable objects, I could get the data via: state.get().

The state I'm attaching auth (which is an object of the user token decoded) and token to, are found in global.

I tried using a selector, but I kept getting errors as well.

Is it okay practice to use ".toJS()" to pull that variables out of the state?

@mgambati
Copy link

I'm doing this way, my authReducer default case returns a Object with isLoading key set to true.

Then on index.js :

// ... imports above
const authSession = findSavedAuthSession()
if (authSession) {
  store.dispatch(loginUserSuccess(authSession))
} else {
  store.dispatch(loginUserFail())
}

findSavedAuthSession function

export function findSavedAuthSession () : AuthState | boolean {
  const token: ?string = localStorage.getItem('auth_token')
  if (token) {
    const decoded: Object = jwt(token)
    decoded.token = token //
    const stillValid: bool = decoded.exp > Date.now() / 1000
    return stillValid ? Object.assign(decoded, { token }): false
  }
  return false
}

Note ta AUTH_LOGIN_SUCCESS and AUTH_LOGIN_FAIL actions set isLoading to false. This way redux-auth-wrapper can know when it ended and redirect to the right routes.

@james-lukensow
Copy link
Author

@mgambati Thanks for the insight!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants