javascript - 无法从 ApolloClient 中的 localStorage 检索更新的 token

标签 javascript authentication graphql react-apollo apollo-client

我正在使用 ApolloGraphQL 实现 React 身份验证。

上下文:
在signin.js 中,当用户单击提交按钮并将其设置为本地存储时,我将生成 token 。
然后,我在 App.js 中检索 token ,以便将其传递给 GraphQL,以便可以在 server.js 中检索它。

问题:
用户单击提交按钮后,我可以在:开发人员工具>应用程序>本地存储中看到新一代 token 。 但它在 App.js 中为“客户端 token ”返回“null”
当我再次登录时,我看到之前生成的 token 为“客户端 token ”的值,这意味着它没有从 LocalStorage 获取更新的 token 。

显然,正因为如此,第一次登录时“服务器端 token ”为空,第二次登录时返回之前生成的 token 。

app/client/src/components/signin.js:

    handleSubmit = (event, SignIn)  => {
        event.preventDefault();
        SignIn().then(({ data }) => {
                localStorage.setItem('token', data.SignIn.token);
                this.clearState();
        })
    }  

app/client/src/app.js:

  //initiating the ApolloClient
const client = new ApolloClient({
  uri: 'http://localhost:4000/graphql',

  fetchOptions: {
    credentials: 'include'
  },
//adding token to the localstorage
  request: operation => {
  const token = localStorage.getItem('token');

  operation.setContext({
      headers:{
          authorization: token
      }
    })
    console.log(`client side token ${token}`);
   },
 //catching the most common network error, if any
  onError: ({ networkError }) => {
    if(networkError){
      console.log('Network Error', networkError);
      }
  }
});

server.js:

const app = express();
app.use(async (req, res, next) => {
const token = req.headers['authorization'];
console.log(`server side token: ${token}`);
  next();
});

最佳答案

您需要某种身份验证中间件,因为 apollo 客户端中的请求仅在构造时被调用,我相信这就是为什么当您重新加载页面时 localStorage 具有以前的 token 。

import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { ApolloLink, concat } from 'apollo-link';

const httpLink = new HttpLink({ uri: '/graphql' });

const authMiddleware = new ApolloLink((operation, forward) => {
  // add the authorization to the headers
  operation.setContext({
    headers: {
      authorization: localStorage.getItem('token') || null,
    }
  });

  return forward(operation);
})

const client = new ApolloClient({
  link: concat(authMiddleware, httpLink),
});

参见https://www.apollographql.com/docs/react/advanced/network-layer/#middleware了解更多详情

关于javascript - 无法从 ApolloClient 中的 localStorage 检索更新的 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56825960/

相关文章:

javascript - 使用与 ES6/7 的变量名称相同的键从变量创建对象

passport.js - 如何使用带有 Passport 和快速 session 的订阅传输 ws

javascript - Gatsby GraphQL 查询多个图像

javascript - XMLHttpRequest 异步不工作,总是返回状态 0

javascript - 保存并退出 ActiveX 对象

javascript - JsViews 似乎不适用于数字属性

python - Django 自定义登录页面

authentication - 如何在spring-security的SecurityContext中存储自定义信息?

authentication - 无效的寄存器选项 "value"必须是一个对象hapi-auth-jwt2

typescript - 将类型分配给 Maybe 类型的嵌套类型的属性