与GraphQL
我想查询使用基本身份验证我graphQL API时收到此错误: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
与GraphQL
我的代码来创建我的NetworkInterface的是:
networkInterface = createNetworkInterface({
uri: graphQlEndpoint.uri,
opts: {
credentials: graphQlEndpoint.credentials
}
});
networkInterface.use([{
applyMiddleware(req, next) {
if (!req.options.header) {
req.options.headers = {};
}
req.options.headers.authorization = 'Basic authorizationCode';
next();
}
}])
我米猜测这里的问题是,在我的Web应用程序进行查询之前,它发送预检请求,这就是我收到错误401。我想知道这是否真的是我在那里遇到错误的原因。
如果是这样,有没有办法解决它?
在这种情况下,是否有另一种认证比基本认证更好?
注:我使用Node.js的,反应,阿波罗客户
感谢您的帮助,您可以给我。
编辑
// Enable Cross Origin Resource Sharing
app.use('*', cors());
// Authorization: a user authentication is required
app.use((req, res, next) => {
if (!getAuthUserName(req)) {
logger('ERROR', 'Unauthorized: authenticated username is missing');
res.status(401);
res.send('Unauthorized: Access is denied due to missing credentials');
}else {
next();
}
});
// Print Schema endpoint
app.use(rootUrl + '/schema', (req, res) => {
res.set('Content-Type', 'text/plain');
res.send(schemaPrinter.printSchema(schema));
});
// Print Introspection Schema endpoint
app.use(rootUrl + '/ischema', (req, res) => {
res.set('Content-Type', 'text/plain');
res.send(schemaPrinter.printIntrospectionSchema(schema));
});
// Stop node app
if (config.graphql.debugEnabled) {
app.use(rootUrl + '/stop', (req, res) => {
logger('INFO', 'Stop request');
res.send('Stop request initiated');
process.exit();
});
}
// GraphQL endpoint
app.use(rootUrl, graphqlExpress(request => {
const startTime = Date.now();
request.uuid = uuidV1();
request.workflow = {
service: workflowService,
context: getWorkflowContext(request)
};
request.loaders = createLoaders(config.loaders, request);
request.resolverCount = 0;
request.logTimeoutError = true;
logger('INFO', 'new request ' + request.uuid + ' by ' + request.workflow.context.authUserName);
request.incrementResolverCount = function() {
var runTime = Date.now() - startTime;
if (runTime > config.graphql.queryTimeout) {
if (request.logTimeoutError) {
logger('ERROR', 'Request ' + request.uuid + ' query execution timeout');
}
request.logTimeoutError = false;
throw('Query execution has timeout. Field resolution aborted');
}
this.resolverCount++;
};
return !config.graphql.debugEnabled ?
{
schema: schema,
context: request,
graphiql: config.graphql.graphiqlEnabled
} :
{
schema: schema,
context: request,
graphiql: config.graphql.graphiqlEnabled,
formatError: error => ({
message: error.message,
locations: error.locations,
stack: error.stack
}),
extensions({ document, variables, operationName, result }) {
return {
requestId: request.uuid,
runTime: Date.now() - startTime,
resolverCount: request.resolverCount,
operationCount: request.workflow.context.operationCount,
operationErrorCount: request.workflow.context.operationErrorCount
};
}
};
}));
请尝试graphql服务器端还增加了CORS。我在这里发布一些代码。
const corsOptions = {
origin(origin, callback){
callback(null, true);
},
credentials: true
};
graphQLServer.use(cors(corsOptions));
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type,Accept');
next();
}
graphQLServer.use(allowCrossDomain);
我认为这可能对您有所帮助。
我编辑了我的服务器代码添加你建议的代码(用'app.use'替换'graphQLServer.use'),但我仍然得到相同的'预检请求不会通过访问控制检查'错误。 – petithomme
当我直接从_localhost/graphql_查询我的**服务器**时,我在** **响应头**中获得了您在** allowCrossDomain **中添加的所有标头。但是,当我从我的**客户端**查询时,我的**响应头文件**中没有任何这些标头。 – petithomme
@petithomme您是否在创建应用程序服务器之后放置了这段代码?有时候代码放置可能会导致不一致 –
您的客户端代码很好,但您可能需要在服务器端启用cors。你可以发布你的节点js服务器的代码吗? (快递我猜?) – azium
你的猜测是有道理的,但我认为它已经启用。我没有自己写,但我在我的问题中添加了我认为您想要查看的部分代码。 – petithomme
你救了吗?没有看到任何新的代码 – azium