我正在尝试创建一个中间件来从标头接收令牌,但它似乎永远不会触发,并且我从未看到我在中间件顶部插入的“hello”日志消息。
const jwt = require('jsonwebtoken');
const { GraphQLError } = require('graphql');
module.exports = async ({ req }) => {
console.log('hello');
const authHeader = req.headers.authorization || '';
if (!authHeader.startsWith('Bearer ')) {
throw new GraphQLError('Authorization header must be provided and must be Bearer token');
}
const token = authHeader.split('Bearer ')[1];
if (!token) {
throw new GraphQLError('Authentication token must be provided');
}
try {
const user = jwt.verify(token, process.env.JWT_SECRET_KEY);
return { user };
} catch (err) {
console.log(err);
throw new GraphQLError('Invalid/Expired token');
}
};
这就是我设置服务器的方式;
jwtmiddleware
是我的中间件的名称
const express = require('express')
const app = express()
const { ApolloServer } = require('@apollo/server');
const { startStandaloneServer } = require('@apollo/server/standalone')
const { ApolloServerPluginDrainHttpServer } = require('@apollo/server/plugin/drainHttpServer');
const { schema } = require('./schema.js');
const { resolvers } = require('./resolvers.js');
const http = require('http');
const cors = require('cors');
const { json } = require('body-parser');
const { expressMiddleware } = require('@apollo/server/express4');
const mongoose = require('mongoose')
const jwtmiddleware = require('./middleware/auth.js')
require('dotenv').config();
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
const start = async() => {
await mongoose.connect('mongodb://localhost:27017/SamichayUsers',{
useNewUrlParser: true,
useUnifiedTopology: true
});
}
const httpServer = http.createServer(app);
const server = new ApolloServer({
schema,
resolvers,
context: async ({ req }) => jwtmiddleware({ req }),
plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
});
const startServer = async () => {
await startStandaloneServer(server, {
listen: { port: 5552 },
});
app.use(
'/graphql',
cors(),
json(),
jwtmiddleware,
expressMiddleware(server, {
context: async ({ req }) => {console.log(req); return ({ token: req.headers.token })}, //no logs
})
);
app.listen(5551, () => {
console.log('Connesso alla porta: 5551');
});
}
start()
startServer();
module.exports = {app}
这是我试图从沙箱发送的查询
UpdateUserName: async (parent, { _id, newName }, context) => {
console.log(context);
const user = await User.findByIdAndUpdate(_id, { userName: newName },);
return user;
}
我创建了一个用作中间件的插件,但我很想知道为什么我的中间件无论如何都没有被触发
const jwt = require('jsonwebtoken');
require('dotenv').config();
const jwtmiddleware = {
async requestDidStart(requestContext) {
try {
const operationType = requestContext.request.operationName;
// Avoid login, register, and GET query from ApolloSandbox
if (['IntrospectionQuery', 'LogUser', 'CreateUser', 'CheckUserIsRegistered'].includes(operationType)) {
return;
}
const headers = requestContext.request.http.headers;
const authHeader = headers.get('authorization');
if (authHeader) {
const token = authHeader.split(' ')[1];
jwt.verify(token, process.env.JWT_SECRET_KEY, (err, decoded) => {
if (err) {
throw new AuthenticationError('Invalid token');
}
console.log('Token verified: ', decoded);
});
} else {
throw new AuthenticationError('Authorization header not present');
}
} catch (error) {
console.error('Error during token verification: ', error.message);
throw error;
}
},
};
module.exports = jwtmiddleware;
const server = new ApolloServer({
schema,
resolvers,
plugins: [ApolloServerPluginDrainHttpServer({ httpServer }), jwtmiddleware],
});
在 Apollo-server 4.x 中,上下文不再是服务器
ApolloServer
的选项,而是 startStandAloneServer
的选项。
此外,您可以将
jwtmiddleware
函数用作 context
而不是中间件。
尝试:
const startServer = async () => {
await startStandaloneServer(server, {
listen: { port: 5552 },
context: jwtmiddleware
});