Authentication 使用GraphQL进行基本身份验证
我在尝试查询使用基本身份验证的graphQL API时收到此错误:Authentication 使用GraphQL进行基本身份验证,authentication,graphql,apollo-client,Authentication,Graphql,Apollo Client,我在尝试查询使用基本身份验证的graphQL API时收到此错误: 对飞行前请求的响应未通过访问控制检查:请求的资源上不存在“访问控制允许来源”标头。起源'http://localhost:3000因此,不允许访问。 我创建网络接口的代码是: networkInterface = createNetworkInterface({ uri: graphQlEndpoint.uri, opts: { credentials: graphQlEndpoint.credent
对飞行前请求的响应未通过访问控制检查:请求的资源上不存在“访问控制允许来源”标头。起源'http://localhost:3000因此,不允许访问。
我创建网络接口的代码是:
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();
}
}])
我猜这里的问题是,在我的webapp进行查询之前,它会发送一个飞行前请求,这就是我收到错误401的地方。我想知道这是否真的是我在那里出错的原因
如果是,有没有办法解决
在这种情况下,是否有其他身份验证比基本身份验证更有效
注意:我使用的是node.js、react、apollo客户端
谢谢你能给我的任何帮助
编辑
// 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服务器端添加COR。我在这里发布了一些代码
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);
我认为这可能会对您有所帮助。请尝试在graphql服务器端添加COR。我在这里发布了一些代码
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);
我认为这可能会对您有所帮助。您正在使用的graphql服务器正在拒绝浏览器发出的飞行前请求,以查看服务器是否将接受浏览器的请求。飞行前请求也称为
OPTIONS
request
服务器只发送状态代码200。所以,除了您看到的CORS代码片段之外,您还需要添加一个检查
这是可以在express应用程序中使用的cors中间件:
module.exports = (req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Methods",
"OPTIONS, GET, POST, PUT, PATCH, DELETE"
);
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
//--------------OPTIONS-------------
if (req.method === "OPTIONS") {
return res.sendStatus(200);
}
next();
};
您正在使用的graphql服务器正在拒绝浏览器发出的飞行前请求,以查看服务器是否将接受浏览器的请求。飞行前请求也称为
OPTIONS
request
服务器只发送状态代码200。所以,除了您看到的CORS代码片段之外,您还需要添加一个检查
这是可以在express应用程序中使用的cors中间件:
module.exports = (req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Methods",
"OPTIONS, GET, POST, PUT, PATCH, DELETE"
);
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
//--------------OPTIONS-------------
if (req.method === "OPTIONS") {
return res.sendStatus(200);
}
next();
};
您的客户机代码很好,但是您可能需要在服务器端启用cors。你能发布你的节点js服务器的代码吗?(表示我在猜测?)你的猜测是有道理的,但我认为它已经启用了。我不是自己写的,但我在我的问题中添加了我认为您需要查看的代码部分。您保存了吗?没有看到任何新代码是的,抱歉,之后马上更新了。如果有其他部分可以帮助的话,请让我知道。很有趣。。如果将
app.use('*',cors())
更改为app.use(cors())
您的客户端代码很好,但可能需要在服务器端启用cors,会发生什么情况。你能发布你的节点js服务器的代码吗?(表示我在猜测?)你的猜测是有道理的,但我认为它已经启用了。我不是自己写的,但我在我的问题中添加了我认为您需要查看的代码部分。您保存了吗?没有看到任何新代码是的,抱歉,之后马上更新了。如果有其他部分可以帮助的话,请让我知道。很有趣。。如果您将app.use('*',cors())
更改为app.use(cors())
我编辑了我的服务器代码以添加您建议的代码(将graphQLServer.use
替换为app.use
)但我仍然得到相同的飞行前请求未通过访问控制检查错误。当我直接从localhost/graphql查询我的服务器时,我会在我的响应标头中获得您在allowCrossDomain中添加的所有标头。但是当我从我的客户机查询时,我的响应标题中没有这些标题。@请问您是否在创建应用服务器之后放置了此代码部分?有些时候,代码放置可能会导致数据引用。我将其放置在之后。启动并将其放置在所有应用程序之前。使用。我已经在app.use(cors())
上写了一行代码,所以我把代码放在那里。我想问题可能是IIS阻止了我的选项飞行前请求,因为它没有授权标头。我正在寻找一种方法,将我的IIS配置为在飞行前请求后返回状态为200的消息。我编辑了服务器的代码以添加您建议的代码(替换graphQLServer。使用app.use
)但我仍然得到相同的飞行前请求未通过访问控制检查错误。当我直接从localhost/graphql查询我的服务器时,我会在我的响应标头中获得您在allowCrossDomain中添加的所有标头。但是当我从我的客户机查询时,我的响应标题中没有这些标题。@请问您是否在创建应用服务器之后放置了此代码部分?有些时候,代码放置可能会导致数据引用。我将其放置在之后。启动并将其放置在所有应用程序之前。使用。我已经在app.use(cors())
上写了一行代码,所以我把代码放在那里。我想问题可能是IIS阻止了我的选项飞行前请求,因为它没有授权标头。我正在寻找一种方法,将我的IIS配置为在飞行前请求后返回状态为200的消息。