Redux如何组织客户端用户身份验证代码?
也很想学习如何最好地将Facebook登录整合到Redux中。
答案 0 :(得分:4)
在我的示例项目中,我只保留了一个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
});
用户完成身份验证流程后,我只需将访问令牌属性设置为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
函数。
答案 1 :(得分:2)
我没有使用Facebook的登录流程,但我认为这是相同的想法。
因此,要登录并存储数据,只需为具有以下字段的用户创建其他reducer:
{
access_token: null,
isLogin: false,
isProcessingLogin: true,
profile: {}
}
当然,您可以拥有更多字段,也可以在此处注册信息(例如, isUserRegistering 或详细信息,无论如何)。
您需要做的所有事情 - 创建 logIn 和 logOut 等方法,这将执行此流程。在其中,只需更改相应的字段即可更新UI以添加加载,错误处理等。
类似于以下代码:
// 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
});
}
我不得不提一下,构建中间件总是附加令牌可能不是一个好主意,如果你的请求必须区分内部reducer是否带有令牌 - 所以,添加它可能会更灵活一点自己表示。
答案 2 :(得分:0)
我通常在会话缩减器中处理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)
}
}
}