当前位置: 首页 > 知识库问答 >
问题:

Apollo客户端未在Nextjs Lamda中发送JWT承载令牌

陶飞英
2023-03-14

authorization未与Apollo一起发送。这会导致您没有执行此操作的适当功能

const apolloClient = ({ cookies: { token = null }, headers }) => {
  const authLink = setContext(_ => {
    console.info(token) //correct tokens
    return {
      headers: {
        ...headers,
        authorization: `Bearer ${token}`,
      },
    }
  })

  return new ApolloClient({
    link: ApolloLink.from([
      onError(({ graphQLErrors, networkError }) => {
          console.error(graphQLErrors, networkError)
      }),
      authLink.concat(
        createHttpLink({
          uri: graphQL,
          credentials: 'same-origin',
          fetch: fetch,
        })
      ),
    ]),
    cache: new InMemoryCache(),
  })
}

我需要在我的NextJS Lamba文件中对自己进行身份验证,该文件现在位于/pages/api/*

这对我来说有点麻烦。我不确定这是唯一的方法,但这是我的大脑带我去的地方。我正在将请求传递到apollo.serverless.js`,以便能够访问Cookie中的承载令牌。

这可能就像我的apollo.client的设置不正确一样简单。

我正在直接测试链接http://localhost:3000/api/users/update/role/dxnlcjoxmtg=,因为带区webhook将使用查询参数直接访问此url。

import { useQuery, useMutation } from '../../../../../lib/apollo/apollo.serverless'
import { updateMemberRole, allUsers } from '../../../queries/users'

export default async (req, res) => {
  let data
  try {
    const mutationInfo = await useMutation(
      {
        mutation: updateMemberRole,
        variables: {
          userId: req.query.userId,
        },
      },
      req
    )
    data = mutationInfo.data
  } catch (err) {
    data = err
  }
  res.status(200).json({ data })
}


Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,en-GB;q=0.8,fr;q=0.7
Cache-Control: no-cache
Connection: keep-alive
Cookie: analyticsCookieAccepted=1; analyticsCookieNoticeClosed=1; _ga=GA1.1.2044509544.1574855120; wordpress_test_cookie=WP+Cookie+check; OPTOUTMULTI=0:0%7Cc4:0%7Cc3:0%7Cc2:0; wp-settings-45=editor%3Dhtml%26libraryContent%3Dbrowse%26imgsize%3Dfull; wp-settings-time-45=1575018303; theme=light; wp-settings-time-1=1575496501; utag_main=v_id:016eacdb7ad1001fa3af49cf1fec01069001606100fb8$_sn:18$_se:1$_ss:1$_st:1575891251585$ses_id:1575889451585%3Bexp-session$_pn:1%3Bexp-session; wordpress_logged_in_86a9106ae65537651a8e456835b316ab=glasshousegames%7C1578351721%7CtL4KMHIW7tTAUuCzUOJd8r6Mu5buST9mheH2tn9WFQs%7C593e133b11f6c0745f577e32d66db0cf1ccfa012504f9015fc64c515d2df77d2; token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3QiLCJpYXQiOjE1NzgwNTgyOTIsIm5iZiI6MTU3ODA1ODI5MiwiZXhwIjoxNTc4NjYzMDkyLCJkYXRhIjp7InVzZXIiOnsiaWQiOiIxMTgifX19.iMSh4KjuON3otpOqO3TXpYAh2bQYu48sqm9pzsgeBis
Host: localhost:3002
Pragma: no-cache
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36
import dotenv from 'dotenv'
import { fetch } from 'cross-fetch/polyfill'
import { createHttpLink } from 'apollo-link-http'
import { ApolloClient } from 'apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { setContext } from 'apollo-link-context'
import { onError } from 'apollo-link-error'
import { ApolloLink } from 'apollo-link'
import { graphQL } from 'app.config'
import ApolloClass, { sortParams } from '~/lib/apollo/apollo.class'

dotenv.config()

const apolloClient = ({ cookies: { token = null }, headers }) => {
  const authLink = setContext(_ => {
    return {
      headers: {
        ...headers,
        authorization: `Bearer ${token}`,
      },
    }
  })

  return new ApolloClient({
    link: ApolloLink.from([
      onError(({ graphQLErrors, networkError }) => {
        if (graphQLErrors)
          graphQLErrors.forEach(({ message, locations, path }) => console.log(`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`))
        if (networkError) console.log(`[Network error]: ${networkError}`)
      }),
      authLink.concat(
        createHttpLink({
          uri: graphQL,
          credentials: 'same-origin',
          fetch: fetch,
        })
      ),
    ]),
    cache: new InMemoryCache(),
  })
}

export const useQuery = async function(query) {
  const { options = {} } = sortParams([...arguments])
  const { loading, data: queryData, error, ...props } = await apolloClient.query({
    query,
    ...options,
  })
  let transformData = {}

  if (queryData) transformData = new ApolloClass(queryData).start()
  return {
    queryData,
    error,
    loading,
    data: transformData,
  }
}

export const useMutation = async function(mutation, req) {
  const { data } = await apolloClient(req).mutate(mutation)
  return { data }
}

// 20200106132714
// http://localhost:3002/api/users/update/role/dXNlcjoxMTg=

{
  "data": {
    "graphQLErrors": [
      {
        "message": "You do not have the appropriate capabilities to perform this action",
        "category": "user",
        "locations": [
          {
            "line": 2,
            "column": 3
          }
        ],
        "path": [
          "updateUser"
        ]
      }
    ],
    "networkError": null,
    "message": "GraphQL error: You do not have the appropriate capabilities to perform this action"
  }
}

因此,我认为问题是我的头没有被发送,因为我无法在这里详细介绍的头中看到它们,当查看http://localhost:3000/api/users/update/role/cm9sztpzdgfuzgfyza==时,我无法在我的头中看到它们

值得一提的是,我正在使用GraphQL和wp-GraphQL以及JWT作为我的身份验证令牌。并使用WP REST API的JWT身份验证处理JWT令牌。我没有引起更多注意的原因是,我在我的头中看不到任何承载someToken,所以我确信,一旦令牌发送过来,一切都正常工作。JWT在我从Cookie进行的所有交互中都正常工作。

RewriteCond %{HTTP:Authorization} ^(.)
RewriteRule ^(.) - [E=HTTP_AUTHORIZATION:%1]
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

<ifmodule mod_headers.c="">
    # SetEnvIf Origin "^(.*\.domain\.com)$" ORIGIN_SUB_DOMAIN=$1
    SetEnvIf Origin "http(s)?://(www\.)?(localhost|now.sh|dev.domain1.games)$" ORIGIN_SUB_DOMAIN=$1
    Header set Access-Control-Allow-Origin "%{ORIGIN_SUB_DOMAIN}e" env=ORIGIN_SUB_DOMAIN
    Header set Access-Control-Allow-Methods: "*"
    Header set Access-Control-Allow-Headers: "Origin, X-Requested-With, Content-Type, Accept, Authorization, Content-Disposition"
</ifmodule>

<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/jpg "access 1 year"
    ExpiresByType image/jpeg "access 1 year"
    ExpiresByType image/gif "access 1 year"
    ExpiresByType image/png "access 1 year"
    ExpiresByType text/css "access 1 month"
    ExpiresByType text/html "access 1 month"
    ExpiresByType application/pdf "access 1 month"
    ExpiresByType text/x-javascript "access 1 month"
    ExpiresByType application/x-shockwave-flash "access 1 month"
    ExpiresByType image/x-icon "access 1 year"
</IfModule>

共有1个答案

钱哲茂
2023-03-14

将此添加到.htaccess文件

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
 类似资料:
  • 我正在为一个全新的前端添加JWT认证到一个遗留的Rails后端。 根据 HTTP 请求,似乎大多数消息来源都建议我通过持有者标头将令牌发送回服务器。 为什么?通过报头发送的附加价值是什么(承载或基本)。我不能简单地把JWT传回到服务器。json并在那里验证令牌。 Authorization标头给我带来了什么好处,更重要的是,Bearer Authorize标头给了我什么好处? 我当然可以简单地效仿

  • 有两个ASP.NET核心Web API使用承载令牌身份验证。这些服务还提供静态文件,这些文件用于同意API进入消费应用程序的目录。所以这两个API都在Azure AD中启用了隐式流。 API2使用jwt-barer授权从Web API控制器调用API1。API2具有访问API1的权限。 来自第三个目录的用户导航到API2服务的SPA。用户被重定向到Azure AD,登录并同意API。用户被重定向回

  • 我将JWT的令牌发送在头中,但客户端需要它在响应的正文中,我如何将它放入响应中:

  • 在angular文档中,提到angular将在post请求的头中自动发送cookie的值。文档链接 但它没有为我发送标题。这是我的密码 Nodejs用于设置cookie的代码 我在app.module.ts中使用了http客户端 **以上代码仅用于调试目的。我没有set-csrf终结点。 但是当我发送帖子请求时,它不会发送任何标题。我不能调试。 我也在angular的github存储库中添加了这个

  • 我在Spring框架中有csrf保护。所以在每个请求中,我都从ajax调用中发送csrf令牌,这是完美的工作。 在ajax

  • 我正在做一个带有用户名和密码的登录屏幕。如果登录成功,服务器将返回令牌。然后,我试图调用另一个函数来获取用户信息,但没有传递授权标头。我正在邮递员上尝试我的服务器方法,它工作得很好,所以我相信问题出在邮件头上。有人能告诉我该怎么做吗? 请注意,result.access_token!=null是true.并且我成功地拿回了令牌。但是它不会被再次传递到第二个url(info)