Skip to content

Instantly share code, notes, and snippets.

@kolodny
Forked from mattiamanzati/handling auth in redux
Last active August 26, 2015 20:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kolodny/a8b9a2c5b73cc3332a31 to your computer and use it in GitHub Desktop.
Save kolodny/a8b9a2c5b73cc3332a31 to your computer and use it in GitHub Desktop.
Auth handling in redux.
Before reading:
This is a soft auth check. Auth check should always be done server side, if not, your rest api are not checking correctly for auth.
1. Auth is in the store.
You need to setup constants for AUTH_SET_TOKEN and AUTH_LOGOUT,
then create the action creators authSetToken(token) and authLogout() action creators.
Then setup a reducer that when AUTH_SET_TOKEN is dispatched, sets the internal state to {token: token},
and when logout is dispatched, clears it.
Now setup a utility function isLoggedIn(state) function, that only checks in state.auth.token exists, this is a soft check.
2. Have a general api http middleware
Every http request to the rest backend should pass through an "API middleware", which basically given an action like
{types: [AUTH_LOGIN_PENDING, AUTH_LOGIN_SUCCESS, AUTH_LOGIN_ERROR], url: 'http....', method: 'post', data: credentials}
executes it's http request, and dispatches immediatly the {type: AUTH_LOGIN_PENDING}, and when http request is done dispatch
{type: AUTH_LOGIN_SUCCESS, data} or {type: AUTH_LOGIN_ERROR, error}
3. Have an auth middleware
This middleware appends the ?token= to every auth request, could be done in the api middleware, but I love to decouple then.
It also appends an error listener for the http request, and if a forbidden http status is given, it dispatches the authLogout() action.
This is the part where the soft auth check becomes a real auth check.
4. Have a store enancher for the redirections
Now, how can I handle user redirections?
I created a store enancher like this that basically wraps the dispatch action, and you can configure the redirects on the enancher.
So when you trigger the AUTH_LOGIN_SUCCESS the redirect will be automatically performed.
Here you can setup an automatic redirect from AUTH_LOGOUT to the login screen.
// import the router replace state action
var {routerReplaceState} = require('./actions');
module.exports = mappings => next => (reducer, initialState) => {
// create a reference to the final store
const store = next(reducer, initialState);
return {
...store,
dispatch(action) {
// actually dispatch the action to the upper store
store.dispatch(action);
// if inside the mappings object exists a record for the current action being triggered
if(mappings[action.type]){
var mapped = mappings[action.type];
// [types.ACT_AUTH_LOGIN_SUCCESS]: [types.SCREEN_MAIN_MENU, {foo: 'bar'}],
if(Array.isArray(mapped) && mapped.length == 2){
store.dispatch(routerReplaceState(mapped[0], mapped[1]));
// [types.ACT_AUTH_LOGIN_SUCCESS]: (dispatch, getState, routerReplaceState) => {},
}else if(typeof mapped === 'function'){
mapped(store.dispatch, store.getState, routerReplaceState);
// [types.ACT_AUTH_LOGIN_SUCCESS]: types.SCREEN_MAIN_MENU,
}else{
store.dispatch(routerReplaceState(mapped))
}
}
// returns the action
return action;
}
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment