首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React样板:实现JWT身份验证。试图从服务中分派动作

React样板:实现JWT身份验证。试图从服务中分派动作
EN

Stack Overflow用户
提问于 2022-06-24 19:59:11
回答 2查看 221关注 0票数 1

环境:--这是我试图在经过尝试和测试的反应样板之上实现的代码。虽然这个样板很棒,但它不包含身份验证。我试图以与样板的现有逻辑相匹配的方式实现自己的身份验证逻辑。

上下文:

我有一个服务/实用程序函数,用于发送带有JWT身份验证头的服务器请求并返回其响应。

目标:

我试图实现逻辑,当使用过期令牌发出请求时,访问令牌会在请求发送到服务器之前自动刷新。

阻止我的是什么:

  1. 我有一个处理访问令牌刷新的传奇。当从容器中调用它时,它工作得很好。但是因为这是一个服务,所以它不知道redux商店。由于这个原因,我无法派遣行动。
  2. 反应样板结构通过在飞行中注入减速器和sagas来工作.这意味着我需要从服务中注入身份验证传奇和还原器(有点感觉不对,不是吗?)然而,佐贺和还原剂注射器是反应副作用,因此,只能在反应组件的内部使用。

我觉得我想要完成的任务非常琐碎(我确信它已经实现了一百万次),但是,我想不出一个解决方案似乎不违背为什么使用Redux或Sagas的整个逻辑。

有人能提供一些见解吗?在附图中,红色文本是我正在努力实现的部分

见下面的代码:

代码语言:javascript
复制
/**
 * Requests a URL, returning a promise
 *
 * @param  {string} url       The URL we want to request
 * @param  {object} [options] The options we want to pass to "fetch".
 *
 * @return {object}           The response data
 */
export default function request( url, options ) {

    const token = makeSelectAccessToken();
    if (!token) throw new Error('No access token found.');

    // Refresh access token if it's expired.
    if (new Date(token.expires) - Date.now() <= 0) {
      // TODO: Attempt to use refresh token to get new access token before continuing
      /** dispatch(REFRESH_ACCESS_TOKEN) **/

      // PROBLEM: can't dispatch actions because the store is not exposed to this service.
      // Secondary challenge: Can't inject Saga or Reducer because the React-boilerplate injectors are React side-effects.
    }

  options = {
    ...options,
    Authorization: `Bearer ${token.token}`, // Adding the JWT token to the request
  };

  return fetch(url, options)
}
EN

回答 2

Stack Overflow用户

发布于 2022-06-27 09:17:32

有多种方法可以做到这一点

1-出口商店

创建新的store.js

代码语言:javascript
复制
import { createStore } from 'redux';
import reducer from './reducer';
//you can add your middleware, sagas, ...
const store = createStore(reducer);

export default store;

将它导入到您的服务中,并在任何地方使用它,但是最终您将为所有用户提供一个单一的存储

  • 缺点:,您将为所有用户提供一个单独的存储(如果您的应用程序使用服务器端呈现,请不要使用此方法)
  • 优点:易用

2-您可以将func添加到中间件并拦截一个操作。

编辑创建存储代码并添加新的中间件以进行授权

代码语言:javascript
复制
const refreshAuthToken = store => next => action => {
  
  const token = makeSelectAccessToken();
  if (!token) throw new Error('No access token found.');

  if(new Date(token.expires) - Date.now() <= 0) {
    // you can dispatch inside store
    this.store.dispatch(REFRESH_ACCESS_TOKEN);
  }

  // continue processing this action
  return next(action);
}

const store = createStore(
  ... //add to your middleware list
  applyMiddleware(refreshAuthToken)
);
  • 缺点:如果这个中间件不能解决您的问题(它很简单),也许您可以需要redux-thunk库。你甚至不能说这是个骗局)
  • 优点:最好和安全的方式满足你的需要,它会工作,每次你呼吁行动。它将像SSR应用程序中的魅力一样工作。

3-或者您可以将存储作为参数从组件发送到请求方法。

  • 缺点:这并不是在组件初始化之后运行的最佳方式,您可以很容易地出错,或者忘记添加到组件中。
  • 优点:至少你可以做你想做的事
票数 1
EN

Stack Overflow用户

发布于 2022-06-26 20:30:02

也许更好的方法是将令牌存储在localStorage上,这样您就不需要访问Redux存储来获得它了。只需获取令牌并以如下方式存储:

代码语言:javascript
复制
localStorage.setItem('token', JSON.stringify(token))

稍后在您的服务中,只需像这样检索:

代码语言:javascript
复制
const token = JSON.parse(localStorage.getItem('token'));

如果您觉得在本地存储中存储令牌不安全,那么还有一个安全-包,它允许对保存到本地存储的数据进行加密。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72748878

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档