我正在寻找一种为我的react-native应用程序创建基本身份验证的方法。 我找不到react-native app的任何好例子。
最好的办法是什么?
感谢。
答案 0 :(得分:57)
当应用程序与强制执行某种形式身份验证的HTTP API进行通信时,应用程序通常会遵循以下步骤:
根据上面定义的工作流程,我们的应用程序首先显示一个登录表单,第2步在用户点击下面发送login
动作创建者的登录按钮时启动:< / p>
/// actions/user.js
export function login(username, password) {
return (dispatch) => {
// We use this to update the store state of `isLoggingIn`
// which can be used to display an activity indicator on the login
// view.
dispatch(loginRequest())
// Note: This base64 encode method only works in NodeJS, so use an
// implementation that works for your platform:
// `base64-js` for React Native,
// `btoa()` for browsers, etc...
const hash = new Buffer(`${username}:${password}`).toString('base64')
return fetch('https://httpbin.org/basic-auth/admin/secret', {
headers: {
'Authorization': `Basic ${hash}`
}
})
.then(response => response.json().then(json => ({ json, response })))
.then(({json, response}) => {
if (response.ok === false) {
return Promise.reject(json)
}
return json
})
.then(
data => {
// data = { authenticated: true, user: 'admin' }
// We pass the `authentication hash` down to the reducer so that it
// can be used in subsequent API requests.
dispatch(loginSuccess(hash, data.user))
},
(data) => dispatch(loginFailure(data.error || 'Log in failed'))
)
}
}
上面的函数中有很多代码,但请注意这一点 大部分代码都在清理响应,并且可以抽象出来。
我们要做的第一件事是发送一个动作LOGIN_REQUEST
来更新我们的商店并让我们知道用户isLoggingIn
。
dispatch(loginRequest())
我们使用它来显示活动指示器(纺车,&#34;正在加载...&#34;等等),并在我们的登录中禁用登录按钮图。
接下来,我们base64编码用户的http basic auth的用户名和密码,并将其传递给请求的标题。
const hash = new Buffer(`${username}:${password}`).toString('base64')
return fetch('https://httpbin.org/basic-auth/admin/secret', {
headers: {
'Authorization': `Basic ${hash}`
}
/* ... */
如果一切顺利,我们会发送LOGIN_SUCCESS
行动,这会导致我们在商店中拥有身份验证hash
,我们将在后续请求中使用该身份验证。< / p>
dispatch(loginSuccess(hash, data.user))
另一方面,如果出现问题,我们也想让用户知道:
dispatch(loginFailure(data.error || 'Log in failed')
loginSuccess
,loginFailure
和loginRequest
动作创建者相当通用,并不真正保证代码示例。请参阅:https://github.com/peterp/redux-http-basic-auth-example/blob/master/actions/user.js)
我们的减速机也很典型:
/// reducers/user.js
function user(state = {
isLoggingIn: false,
isAuthenticated: false
}, action) {
switch(action.type) {
case LOGIN_REQUEST:
return {
isLoggingIn: true, // Show a loading indicator.
isAuthenticated: false
}
case LOGIN_FAILURE:
return {
isLoggingIn: false,
isAuthenticated: false,
error: action.error
}
case LOGIN_SUCCESS:
return {
isLoggingIn: false,
isAuthenticated: true, // Dismiss the login view.
hash: action.hash, // Used in subsequent API requests.
user: action.user
}
default:
return state
}
}
现在我们的商店中有一个身份验证哈希,我们可以将其传递给后续请求的标头。
在下面的示例中,我们为经过身份验证的用户提取朋友列表:
/// actions/friends.js
export function fetchFriends() {
return (dispatch, getState) => {
dispatch(friendsRequest())
// Notice how we grab the hash from the store:
const hash = getState().user.hash
return fetch(`https://httpbin.org/get/friends/`, {
headers: {
'Authorization': `Basic ${hash}`
}
})
.then(response => response.json().then(json => ({ json, response })))
.then(({json, response}) => {
if (response.ok === false) {
return Promise.reject({response, json})
}
return json
})
.then(
data => {
// data = { friends: [ {}, {}, ... ] }
dispatch(friendsSuccess(data.friends))
},
({response, data}) => {
dispatch(friendsFailure(data.error))
// did our request fail because our auth credentials aren't working?
if (response.status == 401) {
dispatch(loginFailure(data.error))
}
}
)
}
}
您可能会发现大多数API请求通常会调度与上述相同的3个操作:API_REQUEST
,API_SUCCESS
和API_FAILURE
,因此大多数请求/响应代码都可以被推入Redux中间件。
我们从商店获取哈希认证令牌并设置请求。
const hash = getState().user.hash
return fetch(`https://httpbin.org/get/friends/`, {
headers: {
'Authorization': `Basic ${hash}`
}
})
/* ... */
如果API响应带有401状态代码,那么我们必须从商店中删除我们的哈希值,并再次向用户显示日志。
if (response.status == 401) {
dispatch(loginFailure(data.error))
}
我一直回答这个问题,只处理http-basic-auth。
我认为这个概念可能保持不变,您可以推送商店中的accessToken
和refreshToken
,并在后续请求中提取它。
如果请求失败,那么您必须发送另一个更新accessToken的操作,然后重新调用原始请求。
答案 1 :(得分:4)
在这个领域,我没有通过例子看到太多,并且认为它肯定需要更多的报道。我自己还没有实现auth,否则我会指出一些代码示例。但是我可以指出你收集的几个链接,可以帮助你朝着正确的方向......
无论您如何执行身份验证,您都需要安全地存储您的访问权限,刷新权限和秘密令牌。在iOS上,我相信您使用keychain来做到这一点,对于Android,它看起来像KeyStore。您可能会发现oblador/react-native-keychain有用,但它还不支持Android looks like it may support android soon。
答案 2 :(得分:0)
我实际上正在制作视频教程系列,至少可以解答您提出的一些问题。视频以及成绩单和示例代码可在此处找到:http://codecookbook.co/post/how-to-build-a-react-native-login-form-with-redux-pt1/