5分钟不活动后,我试图注销并使用户令牌无效。
当应用程序处于“活动”阶段时,我正在使用react-native-user-inactivity,并将timeForInactivity设置为5分钟。但是,当应用程序在后台运行时,它具有预期的行为,尤其是当我将其设置为5分钟时。
我用了1分钟进行测试,并且运行良好,它过去一分钟才用于调用API并使令牌正确失效。但是,当我将其增加到5分钟时,直到应用程序阶段变为“活动”状态时才触发。
在AppState更改事件上使用setTimeout 5分钟时,我有类似的行为。
我只在iOS上尝试过,但是在某处我读到在Android上设置超时超过2分钟会出现错误。正确吗?
使用户令牌无效的最佳方法是什么: 1.当应用程序在后台运行时 2.就在关闭应用程序之前?
答案 0 :(得分:0)
在移至后台(AppState)时,您可以将时间戳记存储在AsyncStorage中(或其他可以保存的东西)。在移至前台时,请检查当前日期是否早于5分钟。如果> 5分钟,请注销。我认为您不需要为此提供图书馆。那是您要找的东西吗?
答案 1 :(得分:0)
您可以使用react-native
包中的PanResponder。
我已使用自定义导航器将Panhandler事件通过screenProps
传递到所有屏幕。检查以下功能,您可能需要根据需要更改代码。这确实对我有用。
import React, { Component } from 'react';
import { Button, PanResponder, Text, View, StyleSheet } from 'react-native';
import { Constants } from 'expo';
// NOTE: you probably want this to be more than 2 seconds?
let TIME_TO_WAIT_FOR_INACTIVITY_MS = 1000;
// NOTE: this is how often you check whether the inactivity threshold has passed
const INACTIVITY_CHECK_INTERVAL_MS = 1000;
const LOG_OUT_POP = 4 * 60 * 1000;
//240,000 sec, 4 min
const LOG_OUT_USER = 60 * 1000;
// 60,000 , 1 min
export default class App extends Component {
state = {};
_lastInteraction = new Date();
_panResponder = {};
_timeIntervalForLoggingOut;
componentWillMount() {
this._panResponder = PanResponder.create({
onStartShouldSetPanResponder: this.handleStartShouldSetPanResponder,
onMoveShouldSetPanResponder: this.handleMoveShouldSetPanResponder,
onStartShouldSetPanResponderCapture: () => false,
onMoveShouldSetPanResponderCapture: () => false,
onPanResponderTerminationRequest: () => true,
onShouldBlockNativeResponder: () => false,
});
this._maybeStartWatchingForInactivity();
}
_maybeStartWatchingForInactivity = () => {
if (this._inactivityTimer) {
return;
}
/**
* - Issue https://github.com/facebook/react-native/issues/12981
* - to over the android performance issue of setTimeout, we have used setInterval and kept checking the time difference every secound.
*/
this._inactivityTimer = setInterval(() => {
if (LOG_OUT_POP <= TIME_TO_WAIT_FOR_INACTIVITY_MS) {
// show Alert timer
console.log('ALERT TIMER 4 Minutes');
clearInterval(this._inactivityTimer);
/*
* Start new timer for loggin out user
* Dont' forget to all clearInterval
*/
this.timeIntervalForLoggingOut = setInterval(() => {
if (LOG_OUT_USER <= TIME_TO_WAIT_FOR_INACTIVITY_MS) {
// show Alert timer
console.log('LOG OUT USER');
clearInterval(this._inactivityTimer);
clearInterval(this._timeIntervalForLoggingOut);
//
} else {
this._setIsInactive();
}
}, INACTIVITY_CHECK_INTERVAL_MS);
/* */
//
} else {
this._setIsInactive();
}
}, INACTIVITY_CHECK_INTERVAL_MS);
};
// NOTE: you almost certainly want to throttle this so it only fires
// every second or so!
_setIsActive = () => {
// this._lastInteraction = new Date();
console.log(TIME_TO_WAIT_FOR_INACTIVITY_MS);
TIME_TO_WAIT_FOR_INACTIVITY_MS += 1000;
if (this.state.timeWentInactive) {
this.setState({ timeWentInactive: null });
}
this._maybeStartWatchingForInactivity();
};
_setIsInactive = () => {
this.setState({ timeWentInactive: new Date() });
clearInterval(this._inactivityTimer);
this._inactivityTimer = null;
};
render() {
return (
<View
style={styles.container}
collapsable={false}
{...this._panResponder.panHandlers}>
<Text style={styles.paragraph}>
Put your app here{' '}
{this.state.timeWentInactive &&
`(inactive at: ${this.state.timeWentInactive})`}
</Text>
<Button
title="Here is a button for some reason"
onPress={() => alert('hi')}
/>
</View>
);
}
handleStartShouldSetPanResponder = () => {
this._setIsActive();
return false;
};
handleMoveShouldSetPanResponder = () => {
this._setIsActive();
return false;
};
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#ecf0f1',
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
color: '#34495e',
},
});
参考:
答案 2 :(得分:0)
试试这个
根据需要修改
import { useCallback, useEffect, useRef, useState } from 'react'
import { AppState } from 'react-native'
import { useLazyApiData, useStores } from '../../data/store'
const inactiveTimeInMinute = 10
const millisecToMins = 60000
export const InactivityHandler = (navigationReset: () => void): any => {
const appState = useRef(AppState.currentState)
const [appStateVisibl, setAppStateVisible] = useState(appState.current)
console.log(appStateVisibl)
const { inactiveTime, resetInactivityTimer, updateInactivityTime, logout } = useStores((store) => ({
inactiveTime: store?.user?.inactiveTime,
resetInactivityTimer: store?.user?.resetInactivityTimer,
updateInactivityTime: store?.user?.updateInactivityTime,
logout: store?.user?.session?.logout,
}))
const [logoutAPI, { state: logoutapistatehandler }] = useLazyApiData(logout)
useEffect(() => {
if (logoutapistatehandler === 'fulfilled' || logoutapistatehandler === 'rejected') {
navigationReset()
}
})
const onAppStateChange = useCallback(
(nextAppState: any) => {
if (appState.current.match(/inactive|background/)) {
updateInactivityTime(Date.now())
}
if (appState.current.match(/inactive|background/) && nextAppState === 'active') {
const differenceInElapsedTime = Date.now() - inactiveTime
const backgroundElapsedTime = Math.floor(differenceInElapsedTime / millisecToMins)
// var ELLAPSED_SECOND = (differenceInElapsedTime % 60000) / 1000 //For testing use second
if (backgroundElapsedTime >= inactiveTimeInMinute) {
logoutAPI()
} else {
resetInactivityTimer()
}
}
appState.current = nextAppState
setAppStateVisible(appState.current)
},
[inactiveTime, logoutAPI, resetInactivityTimer, updateInactivityTime],
)
useEffect(() => {
AppState.addEventListener('change', onAppStateChange)
return () => {
AppState.removeEventListener('change', onAppStateChange)
}
}, [onAppStateChange])
}