【问题标题】:best practices for authentication in react nativeReact Native 中身份验证的最佳实践
【发布时间】:2021-03-09 15:09:35
【问题描述】:

我是 react native 的初学者,我正在创建一个应用程序。我已经对如何制作安全的反应原生应用程序进行了一些研究,但我没有找到太多信息。我自己想出了一个“解决方案”,但我想确保这是正确的方法。因此,如果可能的话,我需要一些 react native/javascript/security 专家的帮助,以快速检查我的方法是否可行?

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

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

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

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

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

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

在我的 react native 应用程序中,这个包装函数位于上下文组件中。这个“身份验证”上下文是我在 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。使用上下文来做这样的事情是一种好习惯吗?

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

【问题讨论】:

    标签: react-native authentication


    【解决方案1】:
    1. 是的,这是有道理的。实际上,我想不出更好的方法来管理您提到的场景。如果您想在发送请求之前对其进行调整,您将需要一个函数来执行此操作。你也可以使用一些钩子,例如onBeforeSendonAfterReceive,但在你的情况下,我没有看到任何额外的价值。

    2. 我不同意删除有效令牌。您仍然可以在每个应用程序开始时向服务器发送请求,以获取用户的最后一个数据——可能在另一台设备上发生了变化——。我不明白使用新会话启动应用程序的逻辑 - 可能需要更多信息?

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

    【讨论】:

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

      【讨论】:

        猜你喜欢
        • 2014-01-23
        • 2013-01-17
        • 2014-06-23
        • 1970-01-01
        • 1970-01-01
        • 2012-08-26
        • 2011-08-17
        • 2010-09-14
        • 1970-01-01
        相关资源
        最近更新 更多