2017-07-24 50 views
1
基本身份驗證

我想查詢使用基本身份驗證我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

回答

0

請嘗試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您是否在創建應用程序服務器之後放置了這段代碼?有時候代碼放置可能會導致不一致 –