React Native身份验证的最佳做法

时间:2020-05-18 21:10:14

标签: react-native authentication

我是React Native的初学者,正在创建一个应用程序。我已经进行了一些有关如何制作安全的React Native应用程序的研究,但没有发现太多信息。我自己想出了一个“解决方案”,但我想确保这是正确的方法。因此,如果可能,我需要一些本机/ javascript /安全专家的帮助下,快速检查我的方法是否可行?

我在本文中包括了3个问题,但显然它们是相关的。我把它们加粗了。随时回答一个或多个问题,谢谢您的回答!

我正在用本机创建一个应用程序。为了使用户能够使用该应用程序,该用户应该创建一个帐户并登录。我使用JSON Web令牌作为访问令牌来授权从应用程序向服务器发出的请求,并标识用户(我将用户ID存储在JSON网络令牌中。)

在我的服务器上,我首先检查访问令牌是否有效。如果是这样,我会从访问令牌中获取用户ID,并使用该用户ID来识别用户。

为了提高安全性,我还使用了刷新令牌,因为访问令牌仅在10分钟内有效。当用户发送带有过期访问令牌的请求时,服务器将以401未经授权状态进行响应。

为了使我的代码更具“可管理性”,我在react native中创建了一个包装器函数。我使用此包装器功能包装了每个“请求功能”(每个对服务器执行GET / POST / PUT / DELETE请求的功能)。该包装器功能检查请求的响应。如果响应状态为200,则响应返回到代码。如果响应状态为401,则刷新令牌将发送到特定端点以获得新的访问令牌。当访问令牌到达应用程序时,将使用新的访问令牌再次进行先前的请求。包装函数还将新的访问令牌存储在(临时)redux(钥匙串或共享首选项)中。 1。包装函数是一个好主意吗?对我来说,它更易于管理,因为现在我正在重用代码。

每次用户打开应用程序时,都会请求一个新的访问令牌,并且当用户关闭该应用程序时,即使当前访问令牌尚未过期,也会将其删除。这样,我要确保每个应用程序“会话”都以新的访问令牌开头。 2。这个可以吗?还是在我仍然拥有(可能是)有效的访问令牌时应该阻止对服务器的不必要请求?

在我的本机应用程序中,该包装函数位于上下文组件中。这种“身份验证”上下文围绕着App.js中的其他组件进行包装,如下所示:

<AuthenticationProvider>
    <AppNavigator />
</AuthenticationProvider>

这样,我的所有其他组件都可以访问包装函数。我的身份验证上下文如下所示:

const AuthenticationContext = createContext({
    accessToken: null,
    wrapperFunction: () => {}
})

const AuthenticationProvider = (props) => {

    let accessToken = null

    const refreshToken = useSelector(state => state.auth.refreshToken)

    const wrapperFunction = () => {
        // wrapper function
        // set the access token
        // await fetch('server endpoint')...     
    }

    return (
        <AuthenticationContext.Provider value={{ accessToken, wrapperFunction }}>
        {props.children}
        </AuthenticationContext.Provider>
    )
}

3。使用上下文进行这样的事情是一种好习惯吗?

在服务器端,我将每个刷新令牌存储在数据库中。当用户请求新的访问令牌时,我检查发送的请求令牌是否仍存在于数据库中。如果不是,我已经撤消了该用户的访问权限,并且该用户应该注销。这样,我要确保可以“管理”用户。

2 个答案:

答案 0 :(得分:0)

  1. 是的,这很有道理。实际上,我想不出一种更好的方法来管理您提到的方案。当您想要在发送请求之前对其进行调整时,您将需要一个函数来执行此操作。您也可以使用一些挂钩onBeforeSendonAfterReceive,但在您的情况下,我认为这没有任何额外的价值。

  2. 我不同意删除有效令牌。您仍然可以在每个应用启动时向服务器发送请求,以获取用户的最新数据(可能在另一台设备上已更改)。我不了解通过新会话启动应用的逻辑-也许更多信息?

  3. 我认为您不需要使用上下文传递wrapperFunction / token。最好是可以根据上下文发送用户数据。您的包装器函数可以直接从asyncStorage访问令牌。每个组件都可以通过导入直接调用该函数。

答案 1 :(得分:0)

  1. 我相信您正在采取使用包装器函数的方法,因为相关的 API 请求是直接在组件中发出的。最佳实践是将此类请求移到组件之外(例如,带有 redux-thunk 等中间件的 Redux 操作)。 最好在发送 API 请求之前检查访问令牌是否已过期(通过解码令牌)并检索新的访问令牌。这将减少对服务器的请求量。您也可以实现一个通用的请求方法来处理此检查。
  2. 我认为,由于您的访问令牌每 10 分钟过期一次,这是不必要的。使用新的访问令牌开始每个会话是否有特定的原因?
  3. 您可以使用上下文传递用户访问详细信息。我认为这是偏好问题。如果您通过通用请求方法处理请求,则不需要传入包装器函数。