gpt4 book ai didi

javascript - React Native + Redux 基本身份验证

转载 作者:行者123 更新时间:2023-12-03 01:56:28 31 4
gpt4 key购买 nike

我正在寻找一种为我的 react native 应用程序创建基本身份验证的方法。我找不到任何反应原生应用程序的好例子。

  • 要登录,应用会将电子邮件/密码 + clientSecret 发送到我的服务器
  • 如果成功,服务器返回accessToken + refreshToken
  • 用户已登录,所有其他请求都包含带有 accessToken 的承载。
  • 如果 accessToken 过期,应用会自动使用刷新 token 请求新的 accessToken。
  • 用户始终保持登录状态,状态应保存在手机中。

最好的方法是什么?

谢谢。

最佳答案

当应用与强制执行某种形式的身份验证的 HTTP API 通信时,应用通常会遵循以下步骤:

  1. 该应用未经过身份验证,因此我们提示用户登录。
  2. 用户输入其凭据(用户名和密码),然后点击“提交”。
  3. 我们将这些凭据发送到 API,并检查响应:
    • 成功时(200 - OK):我们缓存身份验证 token /哈希,因为我们将在每个后续请求中使用此 token /哈希。
      • 如果 token /哈希在任何后续 API 请求期间不起作用(401 - 未经授权),我们需要使哈希/ token 失效并提示用户重新登录。
    • 或者,失败时(401 - 未经授权):我们向用户显示一条错误消息,提示他们重新输入凭据。

登录

根据上面定义的工作流程,我们的应用首先显示登录表单,当用户点击调度 login 操作创建者的登录按​​钮时,第 2 步开始如下:

/// 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())

我们使用它来显示事件指示器(旋转轮、“正在加载...”等),并在登录 View 中禁用登录按钮。

接下来,我们对用户的用户名和密码进行 Base64 编码以进行 http 基本身份验证,并将其传递到请求的 header 。

const hash = new Buffer(`${username}:${password}`).toString('base64')
return fetch('https://httpbin.org/basic-auth/admin/secret', {
headers: {
'Authorization': `Basic ${hash}`
}
/* ... */

如果一切顺利,我们将调度 LOGIN_SUCCESS 操作,这会导致我们的商店中拥有一个身份验证哈希,我们将在后续请求中使用它.

dispatch(loginSuccess(hash, data.user))

另一方面,如果出现问题,我们也想让用户知道:

dispatch(loginFailure(data.error || 'Log in failed')

loginSuccessloginFailureloginRequest 操作创建者相当通用,并不真正保证代码示例。请参阅:https://github.com/peterp/redux-http-basic-auth-example/blob/master/actions/user.js)

reducer

我们的 reducer 也是典型的:

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

后续 API 请求

现在我们的商店中有一个身份验证哈希,我们可以将其传递到后续请求的 header 中。

在下面的示例中,我们正在为经过身份验证的用户获取好友列表:

/// 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_REQUESTAPI_SUCCESSAPI_FAILURE 等大部分请求/响应代码可以推送到 Redux 中间件中。

我们从存储中获取哈希身份验证 token 并设置请求。

const hash = getState().user.hash
return fetch(`https://httpbin.org/get/friends/`, {
headers: {
'Authorization': `Basic ${hash}`
}
})
/* ... */

如果 API 响应包含 401 状态代码,那么我们必须从存储中删除哈希值,并再次向用户显示登录 View 。

if (response.status == 401) {
dispatch(loginFailure(data.error))
}
<小时/>

我已经一般性地回答了这个问题,并且只处理http-basic-auth。

我认为这个概念可能保持不变,您将在存储中推送 accessTokenrefreshToken ,并在后续请求中提取它。

如果请求失败,那么您必须调度另一个更新 accessToken 的操作,然后调用原始请求。

关于javascript - React Native + Redux 基本身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35677062/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com