React Native应用中的用户身份验证

时间:2020-02-02 13:53:28

标签: react-native

我正在构建一个React Native应用程序,用户可以在其中登录。用户登录后,服务器将返回存储在设备上的身份验证令牌(jwt)。全部都可以。

现在,问题在于只要出现“意外”,就对用户进行身份验证。

用户登录并存储令牌后,他将被发送到屏幕“ Main”。在该屏幕上(以及所有其他“受保护的”屏幕上),我要检查auth令牌。我目前具有以下功能(简化):

// get the auth token out of the redux store
const authToken = useSelector(state => state.auth.authToken)

// the function to authenticate a user
const authenticateUser = () => {
    try {
        fetch('http://URL_TO_SERVER/auth/authenticate-user', {
            method: 'post',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + authToken
            }
        })
        .then(response => response.json())
        .then(responseJSON => {
            if (responseJSON.response === 'OK') {
                // user is authenticated
            } else {
                // user is NOT authenticated
            }
        })
}

// only run the function once
useEffect(() => {
    authenticateUser()
}, [])

这有效,但是有一个“滞后”(因为获取返回一个承诺)。当我打开应用程序并在未登录时转到“我”屏幕时,该屏幕仅显示一秒钟,然后,我被重定向到登录屏幕。这样就可以了,但是我不确定这是正确的方法。

我可以在每个屏幕上添加一个“层”,并显示一个加载模式,直到authenticateUser-function运行完毕,但是我认为这样做不是正确的方法。

我的问题是:在React Native应用中保护屏幕安全的最佳方法是什么?我这样做的方式还可以,还是应该切换到其他方法?

谢谢!

编辑:在询问此问题之前,我已经阅读了以下文章。

2 个答案:

答案 0 :(得分:2)

您需要为身份验证提出更好的逻辑。通常,每次打开新屏幕时都不需要检查令牌。即使在您的示例中,您也登录并随后发送到主屏幕,仅检查您刚刚收到的身份验证令牌。同样,当用户显然没有登录时,用户甚至应该看到“转到主屏幕”按钮吗?您是否真的想在应用程序中每次打开新屏幕时都检查令牌?如果令牌在您打开屏幕时是有效的,但是随着时间流逝并且用户停留在同一屏幕上,令牌将无效,会发生什么?

尝试一下:

  1. 创建Redux存储(例如reducer)的一部分,以处理当前身份验证状态。简单的“ isAuthenticated”标志将对开始起作用
  2. 您可以从连接到redux的任何屏幕访问此标志
  3. 收到JWT时,您可以阅读它的到期日期。因此,如果您在5分钟前刷新了令牌,并且令牌在接下来的2小时内不会过期,则无需检查令牌是否有效,因为您可以通过在任何时间将到期日与当前日期进行比较来假设
  4. 使用“ isAuthenticated”标志确定是否显示“转到主屏幕”按钮,以便注销的用户甚至看不到该按钮
  5. 如果您需要更多控制权,请进入导航以检查用户尝试导航至的位置,并通过在redux存储中检查“ isAuthenticated”标志来允许/拒绝该行为。看看herehere
  6. 创建一个服务来跟踪令牌的到期日期,并在需要时提前刷新令牌,或者定期检查当前令牌是否有效,如果无效,则将“ isAuthenticated”设置为false。围绕您的网络功能创建包装器(在您的示例中为fetch),并在响应服务器的任何请求时收到状态401通知该服务,以便该服务可以刷新令牌并重复请求,或者让用户知道他已登录出

答案 1 :(得分:0)

看看我认为实现此目标的最佳方法是在应用程序中添加一个启动画面,在那里您可以转移逻辑(如果令牌存在),您可以重定向到主屏幕或loginScreen。

像这样:

在Splashscreen.js中

componentDidMount(){

AsyncStorage.getItem('token') ? navigation.navigate('Home'):navigation.navigate('Login')
}

希望它会有所帮助。毫无疑问地