如何使用 react-redux 存储令牌并在多个 axios 请求中使用它?
Posted
技术标签:
【中文标题】如何使用 react-redux 存储令牌并在多个 axios 请求中使用它?【英文标题】:How to use react-redux to store a token and use it on multiple axios request? 【发布时间】:2018-04-28 09:36:13 【问题描述】:我正在使用 react native 构建一个应用程序,该应用程序需要我使用令牌在同一个 API 上执行多个 get request
。
假设网址是这样的
令牌 URL = https://test.co/v1/tokens
,API URL 1 = https://test.co/v1/students
和 API URL 2 = https://test.co/v1/cars
首先,为了从任一 API URL 获取数据,我是这样写的
students_actions.js
的示例
import axios from 'axios';
import FETCH_STUDENT from './types';
const TOKEN_URL = '...'
const STUDENT_URL = '...'
export const fetchStudent = (callback) => async (dispatch) =>
axios.post(TOKEN_URL,
email: 'email',
password: 'password',
role: 'user'
)
.then((response) =>
const accessToken = response.data.token;
//console.log(accessToken);
axios.get(STUDENT_URL,
headers: 'Authorization': 'Bearer '.concat(accessToken)
)
.then((studentResponse) =>
dispatch( type: FETCH_STUDENT, payload: studentResponse.data );
callback();
)
.catch((e) =>
console.log(e);
);
)
.catch((error) =>
console.log(error);
);
;
students_reducers.js
的示例
import FETCH_STUDENT from '../actions/types';
const INITIAL_STATE =
data: []
;
export default function (state = INITIAL_STATE, action)
switch (action.type)
case FETCH_STUDENT:
return action.payload;
default:
return state;
并像这样在渲染函数中调用它
//some code
import connect from 'react-redux';
import * as actions from '../actions';
onButtonPressProfile = () =>
this.props.fetchStudent(() =>
this.props.navigation.navigate('Profile');
);
class StudentProfile extends Component
render()
return(
<View><Text>this.props.students.name</Text></View>
);
function mapStateToProps( students )
return students: students.data ;
export default connect(mapStateToProps, actions)(StudentProfile);
虽然这一切都在正常运行,但我觉得 students_actions.js
可以通过编写用于在其他文件中检索令牌的代码并在 students_actions.js
中为 GET request
调用回值来进一步简化。
原因是我不必每次想访问students
或cars
时都请求令牌。可以说,我确实请求了一次,我可以使用相同的令牌 24 小时来访问 API。一旦过期,我必须再次请求令牌才能再次访问 API。
我已经为token_actions.js
和token_reducer.js
编写了代码。下面是两个代码。
token_actions.js
//import library
// this code works
const TOKEN_URL = apiConfig.url + 'tokens';
const auth =
email: 'email',
password: 'password',
role: 'user'
;
export const fetchToken = () => async (dispatch, getState) =>
axios.post(TOKEN_URL, auth)
.then((response) =>
dispatch( type: FETCH_TOKEN, payload: response.data.token );
)
.catch((error) =>
console.log(error);
);
;
token_reducer.js
import
FETCH_TOKEN
from '../actions/types';
const INITIAL_STATE =
data: []
;
export default function (state = INITIAL_STATE, action)
switch (action.type)
case FETCH_TOKEN:
return action.payload;
default:
return state;
students_actions.js
axios.get(STUDENT_URL, headers:
'Authorization': 'Bearer '.concat(here is the value from token_actions))
现在我被困在如何将有效负载从token_actions.js
调用/导入到students_actions.js
中?我应该使用mapStateToProps
还是有其他方法可以做到这一点?
目前,此应用还没有任何认证功能。它基本上是一个显示从 API 获取的数据的应用程序。
我主要根据我在网上找到的示例编写了这个应用程序,对于这个案例,我找到了这个example,但似乎并不是我真正想要实现的目标。
我不太了解 javascript,所以如果有人能指出与此案例相关的任何链接,或者 *** 上的相同问题以及一些建议,我将非常高兴。
谢谢。
【问题讨论】:
【参考方案1】:我要做的合乎逻辑的事情是创建类似 AuthReducer 的东西,您可以在其中存储令牌和刷新令牌。这是我的基本 AuthReducer 的示例:
export const INITIAL_STATE =
oAuthToken: '',
refreshToken: '',
;
export default AuthReducer = (state = INITIAL_STATE, action) =>
switch (action.type)
case REFRESH_OAUTH_DATA:
const oAuthToken, refreshToken = action.payload;
return ...state, oAuthToken, refreshToken ;
case LOGOUT:
return INITIAL_STATE;
case LOGIN_FETCH_SUCCESS:
const oAuthToken, refreshToken = action.payload;
return ...state, oAuthToken, refreshToken ;
default:
return state;
;
现在您可以使用 getState 方法在您的操作中获取令牌:
export const fetchStudent = (callback) => async (dispatch, getState) =>
const token = getState().AuthReducer.oAuthToken;
....
;
请记住,如果您使用的是 ES6,您可能还想使用 await:
export const fetchStudent = (callback) => async (dispatch, getState) =>
try
const accessToken = getState().AuthReducer.oAuthToken;
let response = await axios.get(STUDENT_URL,
headers: 'Authorization': 'Bearer '.concat(accessToken)
)
dispatch( type: FETCH_STUDENT, payload: response.data );
callback();
catch(e)
console.log(e);
;
这样您的代码更易于阅读和维护。
【讨论】:
我应该如何导入AuthReducer
?是不是像import AuthReducer from './AuthReducer';
之上的students_actions.js
?
不,getState 方法是您的 redux 存储中的一个方法,由于 redux-thunk,它可以在您的操作中使用。您无需在操作中导入 reducer 即可访问它。
我通常喜欢在顶层定义一个 API 文件夹,每个 API 功能都有自己的文件夹,并且在执行 fetch 所需的操作和一个 reducer 来保存请求的状态和结果.
嗨,我尝试了你的基本AuthReducer
设置,eslint 给了我错误AuthReducer is not defined
。我应该在哪里定义它?
你是怎么导入的?还是在定义它的时候?以上是关于如何使用 react-redux 存储令牌并在多个 axios 请求中使用它?的主要内容,如果未能解决你的问题,请参考以下文章
为啥不将 JWT 访问令牌存储在内存中并在 cookie 中刷新令牌?
将 JWT 令牌存储在共享首选项中?并在整个应用程序中检索价值?