Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flow for authenticating user with Redux [closed]

What is the Redux way to organize client-side user authentication code?

Would also love to learn how to best integrate Facebook login into Redux.

like image 664
gusaiani Avatar asked Nov 17 '15 15:11

gusaiani


2 Answers

In my example project, I simply kept an authed reducer that handled all authenticated user data. The initial state and reducer looks like this:

const initialState = {
    accessToken: null,
    followings: {},
    likes: {},
    playlists: [],
    user: null
};

export default function authed(state = initialState, action) {
    switch(action.type) {
    case types.RECEIVE_ACCESS_TOKEN:
        return Object.assign({}, state, {
            accessToken: action.accessToken
        });

After the user completes the auth flow, I simply set the access token property in the authed state, and use that to verify whether a user is authenticated throughout my app. i.e.

if (authed.accessToken) {
  // display or do something different for logged in user
}

After successful authentication, I also set a cookie. When the user comes back, I read the access token from the cookie and test if it's still valid (for Facebook it might be using it with the /me endpoint).

If the user logs out, I simply set the authed state back to the initialState and unset the cookie.

case types.RESET_AUTHED:
    return Object.assign({}, initialState);

Simple, but it works for me. You can check out the code here:

https://github.com/andrewngu/sound-redux/blob/master/scripts/reducers/authed.js https://github.com/andrewngu/sound-redux/blob/master/scripts/actions/authed.js

☝ This file is a bit hairy, but just check out initAuth, loginUser, logoutUser, receiveAccessToken, resetAuthed functions.

Demo: https://soundredux.io

like image 79
Andrew Nguyen Avatar answered Oct 21 '22 04:10

Andrew Nguyen


I didn't work with Facebook's login flow, but I think it would be the same idea.

So, to log in and store data, just create additional reducer for user with following fields:

{
   access_token: null,
   isLogin: false,
   isProcessingLogin: true,
   profile: {}
}

Of course, you could have a lot more fields, you could put registering information here as well (for instance, isUserRegistering, or details, whatever).

All that you have to do – create methods like logIn and logOut, which will do this flow. In them, just change corresponding fields to update your UI to add loading, error handling, and so forth.

Something like following code:

    // action creator
    const logIn = (params) => {
      return dispatch => {
         dispatch({ type: 'PROCESSING_LOGIN' });
         makeAPICall(params)
            .then(
                res => dispatch({ type: 'SUCCESS_LOGIN', payload: res }),
                err => dispatch({ type: 'FAIL_LOGIN', payload: err })
            );
      };
    };

    // reducer
    ['PROCESSING_LOGIN'](state) => {
        return Object.assign({}, state, {
           isProcessingLogin: true
        });
    },
    [SUCCESS_LOGIN](state, action) => {
        return Object.assign({}, state, {
            isLogin: true,
            isProcessingLogin: false,
            access_token: action.payload.meta.access_token
        });
    }

I have to mention, that building middleware to always append token could be not so good idea, if your requests have to be differentiating inside reducers whether they are with token or not – so, it could be a bit more flexible to add token by yourself.

like image 32
Bloomca Avatar answered Oct 21 '22 02:10

Bloomca