如何使用 Apollo 从 GraphQL Mutation 设置 Auth token cookie

Posted

技术标签:

【中文标题】如何使用 Apollo 从 GraphQL Mutation 设置 Auth token cookie【英文标题】:How to set Auth token cookie from GraphQL Mutation with Apollo 【发布时间】:2019-08-22 03:10:30 【问题描述】:

我正在使用来自 graphql-yoga 的 GraphQLServer 来处理请求。此时我的后端能够与我的 React 前端进行通信,并且我可以进行 graphql 查询并获得很好的响应。

我最近被告知我应该使用令牌设置一个 cookie,而不是在突变响应中返回它。所以我正在尝试切换,但突变没有设置 cookie。

server.js(节点)

import  GraphQLServer, PubSub  from 'graphql-yoga';
import resolvers, fragmentReplacements from './resolvers/index'
import prisma from './prisma'

const pubsub = new PubSub()

export default new GraphQLServer(
  typeDefs: './src/schema.graphql',
  resolvers,
  context(request) 
    return 
      pubsub,
      prisma,
      request, //fragmentReplacements[], request, response
    
  ,
  fragmentReplacements
);

Mutation.js(节点)

export default 
  async createUser(parent, args, prisma, request, info) 
    const lastActive = new Date().toISOString()
    const user = await prisma.mutation.createUser( data: ...args.data, lastActive )
    const token = generateToken(user.id)
    const options = 
      maxAge: 1000 * 60 * 60 * 24, //expires in a day
      // httpOnly: true, // cookie is only accessible by the server
      // secure: process.env.NODE_ENV === 'prod', // only transferred over https
      // sameSite: true, // only sent for requests to the same FQDN as the domain in the cookie
    
    const cookie = request.response.cookie('token', token, options)
    console.log(cookie)
    return user
  ,
  // more mutations...

console.log(cookie) 输出带有附加的 cookie

index.js(反应)

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App';
import ApolloClient,  InMemoryCache, create  from 'apollo-boost';
import ApolloProvider from 'react-apollo'

const client = new ApolloClient(
  uri: 'http://localhost:4000',
  cache: new InMemoryCache(),
  credentials: 'include',
  request: async operation => 
    operation.setContext(
      fetchOptions: 
        credentials: 'same-origin'
      
    )
  ,
)

ReactDOM.render(
  <ApolloProvider client=client>
    <App />
  </ApolloProvider>, 
  document.getElementById('root'));

所以我的问题是:

    有没有更好的方法来使用 GraphQL 进行身份验证,或者在 auth 突变中使用 cookie 设置令牌是否合适? 假设这是一个不错的方法,我如何从突变中设置 cookie

感谢您的宝贵时间!

【问题讨论】:

你设置 cookie 的方式是正确的,我已经从 Express 应用程序中成功设置了这种方式的 cookie。当您说它“未设置”时,您的确切含义是什么?它在 UI 的开发者控制台中不可见吗?关于第一个问题 - 您可以使用 JWT 并将令牌作为响应的一部分而不是 cookie 返回。它似乎是 GraphQL 中的标准身份验证/授权机制,我过去成功地实现了这一点。 在基于浏览器的客户端中不建议返回令牌并直接在后续请求中使用它,因为它可能被攻击者使用 JS 窃取,而设置了 HTTPOnly 和 Secure 标志的 cookie 无法访问JS. @Jaryl 谢谢,继续使用安全的同域 cookie。 【参考方案1】:

您需要在 ApolloClient 中包含凭据

 fetchOptions: 
    credentials: 'include'
 

【讨论】:

以上是关于如何使用 Apollo 从 GraphQL Mutation 设置 Auth token cookie的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Apollo Server 端点获得完整的 GraphQL 架构?

如何使用 apollo 客户端从 schema.graphql 中提取 typescript 接口:codegen

如何使用 Apollo 从 GraphQL Mutation 设置 Auth token cookie

如何在 apollo 的 graphql-gql 中使用从 npm 包导入的自定义 graphQL 类型

如何将数据从反应组件传递到 Apollo graphql 查询?

如何使用 React-Apollo 处理 GraphQL 错误?