Подтвердить что ты не робот

Поток для аутентификации пользователя с помощью Redux

Что такое способ Redux для организации кода проверки подлинности на стороне клиента?

Также хотелось бы узнать, как лучше всего интегрировать Facebook в Redux.

4b9b3361

Ответ 1

В моем примере проекта я просто сохранил редуктор authed, который обрабатывал все аутентифицированные пользовательские данные. Начальное состояние и редуктор выглядит следующим образом:

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
        });

После того как пользователь завершит поток auth, я просто установил свойство токена доступа в состоянии authed и использую его для проверки подлинности пользователя во всем приложении. т.е.

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

После успешной проверки подлинности я также установил файл cookie. Когда пользователь вернется, я прочитаю токен доступа из файла cookie и протестирую, если он все еще действителен (для Facebook он может использовать его с конечной точкой /me).

Если пользователь выходит из системы, я просто возвращаю состояние authed в initialState и удаляет файл cookie.

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

Простой, но он работает для меня. Вы можете проверить код здесь:

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

☝ Этот файл немного волосатый, но просто проверьте функции initAuth, loginUser, logoutUser, receiveAccessToken, resetAuthed.

Демо: https://soundredux.io

Ответ 2

Я не работал с потоком входа в Facebook, но думаю, что это будет та же идея.

Итак, чтобы регистрировать и хранить данные, просто создайте дополнительный редуктор для пользователя со следующими полями:

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

Конечно, у вас могло бы быть больше полей, вы могли бы также зарегистрировать здесь информацию (например, isUserRegistering или подробности, что угодно).

Все, что вам нужно сделать - создать такие методы, как logIn и logOut, которые будут выполнять этот поток. В них просто измените соответствующие поля, чтобы обновить свой пользовательский интерфейс, чтобы добавить загрузку, обработку ошибок и т.д.

Что-то вроде следующего кода:

    // 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
        });
    }

Я должен упомянуть, что создание промежуточного программного обеспечения, которое всегда добавляет токен, может быть не очень хорошей идеей, если ваши запросы должны быть дифференцированы внутри редукторов независимо от того, имеют ли они токен или нет - так что это может быть немного более гибким, чтобы добавить токен самостоятельно.

Ответ 3

Я обычно обрабатываю auth в редукторе сеанса, а затем определяю функцию промежуточного программного обеспечения authorized для проверки того, были ли выполнены определенные условия, а если нет - перенаправление. До сих пор он работал довольно хорошо.

Изменить, с простым примером:

export default function authorized(store) {
  return (next) => {
    return (action) => {
      const { session: { loggedIn }} = store.getState()

      if (!loggedIn) {
        const session = cookie.load(sessionCookie.name)

       if (session) {
         next(restoreSession(session, activeBrand))

        // Not logged in, redirect.
       } else {
         next(replaceState({}, '/login'))
       }
     } 

     return next(action)
    }
  }
}