首页 > 解决方案 > 带有 Passport JWT 的 Apollo 服务器

问题描述

我正在尝试使用护照 JWT 实现 graphql,但行为不是我所期望的。

graphql 端点不应该通过身份验证关闭,因为一些查询是公开的,我想知道如果用户使用解析器登录,如何让 graphql 打开并在内部过滤?

那是我现在的代码,它与 JWT 一起正常工作,但它正在关闭 graphql 端点并返回“未授权”,除非我指定一个令牌。

import express from 'express'
import { ApolloServer } from 'apollo-server-express'

import passport from 'passport'
import passportJWT from 'passport-jwt'

import schema from './schemas'

const { JWT_SECRET } = process.env

const path = '/graphql'

// ...

const users = [
  {
    id: 1,
    name: 'John',
    email: 'john@mail.com',
    password: 'john123'
  },
  {
    id: 2,
    name: 'Sarah',
    email: 'sarah@mail.com',
    password: 'sarah123'
  }
]

// ...

const { Strategy, ExtractJwt } = passportJWT

const params = {
  secretOrKey: JWT_SECRET,
  jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken()
}

// ...

const strategy = new Strategy(params, (payload, done) => {
  const user = users[payload.id] || null

  if (user) {
    return done(null, {
      id: user.id
    })
  }

  return done(new Error('The user has not been found'), null)
})

passport.use(strategy)

// ...

const app = express()

passport.initialize()

app.use(path, passport.authenticate('jwt', { session: false }))

// ...

const server = new ApolloServer({
  schema
})

server.applyMiddleware({
  app,
  path
})

app.listen(
  {
    port: 4000
  },
  () => console.log(`The GraphQL server is running on port ${GRAPHQL_PORT}`)
)

标签: node.jsexpressjwtgraphqlapollo-server

解决方案


如果 JWTToken 不存在,则 passport-jwt 将失败,并将未授权状态传递给 info。你可以像下面这样处理它们

app.use(path, bodyParser.json(), function(req, res, next) {
    passport.authenticate('jwt', (err, user, info) => {
        if (err) { res.status(500).send({"error": err}); return; }
        next();
    })(req, res, next);
});

推荐阅读