ReactiveSearch 的 Elasticsearch CORS 错误

Posted

技术标签:

【中文标题】ReactiveSearch 的 Elasticsearch CORS 错误【英文标题】:Elasticsearch CORS error with ReactiveSearch 【发布时间】:2018-11-16 09:18:13 【问题描述】:

我已经有一个用于 jwt 身份验证的 Node/Express 服务器设置与我的 Create React 应用程序一起使用。我正在使用 CORS npm 包和简单的中间件 app.use(cors()); 来解决预期的 CORS 相关问题及其正常工作。

现在我想将 Elasticsearch 和 ReactiveSearch 添加到我的 React 应用程序中,并试图弄清楚如何解决我本地 ES 实例的 CORS 问题。

我的第一个猜测是我需要创建一个单独的 searchRoutes.js 文件并实现 ES 在本地工作和连接我的 React 应用所需的任何 CORS 代码?

我一直在关注 ReactiveSearch 的文档(使用 http-proxy-middleware)但没有任何成功...不断收到此 CORS 错误:无法加载 http://localhost:9200/query-index/_msearch?:请求标头字段内容类型为预检响应中的 Access-Control-Allow-Headers 不允许。

尽管我相信我已经实现了 CORS 预检solution

app.options('/autocomplete', cors()); // this is for pre-flight

欢迎任何建议、链接或教程

更新:这是我的 Nodejs index.js(服务器)

require('dotenv').config();
import express from 'express';
import http from 'http';
import bodyParser from 'body-parser';
import morgan from 'morgan';
import mongoose from 'mongoose';
import proxy from 'http-proxy-middleware';
import cors from 'cors';
import compression from 'compression';

// import dotenv from 'dotenv'; // added
import router from './router';
// import  dbConfig  from './config';

// Express app init
const app = express();
// app.options('/query-index', cors()); // this is for pre-flight

/* This is where we specify options for the http-proxy-middleware
 * We set the target to appbase.io backend here. You can also
 * add your own backend url here */
const options = 
    // target: 'https://scalr.api.appbase.io/',
    target: 'http://localhost:9200',
    changeOrigin: true,
    // onProxyReq: (proxyReq, req) => 
    //     proxyReq.setHeader(
    //         'Authorization',
    //         `Basic $btoa('cf7QByt5e:d2d60548-82a9-43cc-8b40-93cbbe75c34c')`
    //     );
    //     /* transform the req body back from text */
    //     const  body  = req;
    //     if (body) 
    //         if (typeof body === 'object') 
    //             proxyReq.write(JSON.stringify(body));
    //          else 
    //             proxyReq.write(body);
    //         
    //     
    // 
;

// Connect MongoDB
mongoose.connect(process.env.MONGODB_URI);
mongoose.set('debug', true);

// middleware
app.use(compression());
app.use(morgan('combined'));
app.use(cors()); // cors middleware
// https://***.com/a/38345853/3125823
// Enable CORS from client-side from slatepeak
// app.use((req, res, next) => 
//   res.header('Access-Control-Allow-Origin', 'http://localhost:3333', 'http://localhost:9200'); // this can also be a list of urls
//   res.header('Access-Control-Allow-Methods', 'OPTIONS, PUT, GET, POST, DELETE');
//   res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-Auth-Token, Origin, Content-Type, Accept, Authorization, Access-Control-Allow-Credentials');
//   // res.header('Access-Control-Allow-Credentials', 'true');
//   next();
// );
app.use(bodyParser.json( type: '*/*' ));

/* This is how we can extend this logic to do extra stuff before
 * sending requests to our backend for example doing verification
 * of access tokens or performing some other task */
app.use('/query-index', (req, res, next) => 
    const  body  = req;
    console.log('Verifying requests ✔', body);
    /* After this we call next to tell express to proceed
     * to the next middleware function which happens to be our
     * proxy middleware */
    next();
);

/* Here we proxy all the requests from reactivesearch to our backend */
app.use('/query-index', proxy(options));

app.options('/query-index', cors()); // this is for pre-flight
app.get('/query-index', cors(), function(req, res, next) 
  res.json( msg: 'This is CORS-enabled for route \/query-index');
);

router(app);

const authPort = process.env.PORT || 3333; // default
const authServer = http.createServer(app);
authServer.listen(authPort);
console.log('Auth Server listening on:', authPort);

【问题讨论】:

您能发布更多代码或回购链接吗?它应该可以工作,这里是client 和server 示例以防万一 @DivyanshuMaithani - 我也应该能够使用 npm cors 包完成这项工作,对吧?不仅仅是 http-proxy-middleware。 @DivyanshuMaithani - 刚刚为 Nodejs 发布了我的整个 index.js,包括 CORS 和 http-proxy-middleware 代码,请看看我做错了什么 @DivyanshuMaithani - 如果我在我的本地 ES 中放置了正确的 CORS 设置,我是否仍然需要使用来自 npm 或 http-proxy-middleware 的 CORS 等包来让 ES 和 ReativeSearch 相互交谈。 【参考方案1】:

首先,您可以摆脱它,为所有请求简单明了地启用 CORS:

app.use(cors())

假设您仍想使用单路由:您的代码引用了“自动完成”路由,您发布的返回 CORS 错误的链接指的是不同的路由“query_index/..”,因为您选择了要采用单路由启用方式,您需要修复此问题并使用启用 CORS 的匹配路由。

从您发布的内容来看,您的解决方案看起来更不完整。 如果你看solution:

app.get('/products/:id', cors(), function (req, res, next) 
  res.json(msg: 'This is CORS-enabled for a Single Route')
)

并将其与您的比较,您应该为您的路由添加一个回调,因为回调是您的逻辑发生的地方(转移到控制器等)。 这可能看起来像这样:

app.get('/autocomplete', cors(), function (req, res, next) 
  res.json(msg: 'This is CORS-enabled for route \/autocomplete')
)

【讨论】:

我想我明白你在说什么。是的,/autocomplete 是客户端路由并在端口 3000 上运行,ES 是后端在 9200 上。只需使用 CORS 配置稍微调整路由。用新的眼光看待这个问题 - 谢谢。【参考方案2】:
http.cors.enabled: true
http.cors.allow-credentials: true
http.cors.allow-origin: '*'
http.cors.allow-headers: X-Requested-With, X-Auth-Token, Content-Type, Content-Length, Authorization, Access-Control-Allow-Headers, Accept 

您需要将这些 cors 权限添加到您的 elasticsearch.yml 配置文件中

【讨论】:

以上是关于ReactiveSearch 的 Elasticsearch CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot集成ElasticSearch 02使用 spring-boot-starter-data-elasticsearch 集成并使用高级客户端

spring整合Elasticsearch

Kibana安装

elasticsearch

es索引的RestHighLevelClient实现

EnableReactiveMongoRepositories和ElasticSearch