与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 
     }; 
     } 
    }; 
})); 
+1

您的客户端代码很好,但您可能需要在服务器端启用cors。你可以发布你的节点js服务器的代码吗? (快递我猜?) – azium

+0

你的猜测是有道理的,但我认为它已经启用。我没有自己写,但我在我的问题中添加了我认为您想要查看的部分代码。 – petithomme

+0

你救了吗?没有看到任何新的代码 – azium

请尝试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); 

我认为这可能对您有所帮助。

+0

我编辑了我的服务器代码添加你建议的代码(用'app.use'替换'graphQLServer.use'),但我仍然得到相同的'预检请求不会通过访问控制检查'错误。 – petithomme

+0

当我直接从_localhost/graphql_查询我的**服务器**时,我在** **响应头**中获得了您在** allowCrossDomain **中添加的所有标头。但是,当我从我的**客户端**查询时,我的**响应头文件**中没有任何这些标头。 – petithomme

+0

@petithomme您是否在创建应用程序服务器之后放置了这段代码?有时候代码放置可能会导致不一致 –