“在建立安全 TLS 连接之前断开客户端网络套接字” - Neo4j/GraphQL

Posted

技术标签:

【中文标题】“在建立安全 TLS 连接之前断开客户端网络套接字” - Neo4j/GraphQL【英文标题】:"Client network socket disconnected before secure TLS connection was established" - Neo4j/GraphQL 【发布时间】:2020-08-06 12:10:21 【问题描述】:

使用yarn start:devawait app.listen(3200); 启动 NestJS 和 GraphQL。尝试连接到我的 Neo4J 桌面时,我在尝试通过 localhost:3200/graphQL 获取我的查询时收到此错误:

 "errors": [
   
     "message": "Client network socket disconnected before secure TLS connection was established",
     "locations": [
       
         "line": 2,
         "column": 3
       
     ],
     "path": [
       "getMovies"
     ],
     "extensions": 
       "code": "INTERNAL_SERVER_ERROR",
       "exception": 
         "code": "ServiceUnavailable",
         "name": "Neo4jError"
       
     
   
 ],
 "data": null

所以我认为我的本地 Neo4J 桌面图形运行不正确,但我似乎找不到任何解决方法。目前我有一个 config.ts 文件,其中包含:

export const HOSTNAME = 'localhost';
export const NEO4J_USER = 'neo4j';
export const NEO4J_PASSWORD = '123';

还有一个文件neogql.resolver.ts

import 
  Resolver,
  Query,
  Args,
  ResolveProperty,
  Parent,
 from '@nestjs/graphql';
import  HOSTNAME, NEO4J_USER, NEO4J_PASSWORD  from '../config';
import  Movie  from '../graphql';
import  Connection, relation, node  from 'cypher-query-builder';
import  NotFoundException  from '@nestjs/common';
const db = new Connection(`bolt://$HOSTNAME`, 
  username: NEO4J_USER,
  password: NEO4J_PASSWORD,
);
@Resolver('Movie')
export class NeogqlResolver 
  @Query()
  async getMovies(): Promise<Movie> 
    const movies = (await db
      .matchNode('movies', 'Movie')
      .return([
        
          movies: [ id: 'id', title: 'title', year: 'year' ],
        ,
      ])
      .run()) as any;
return movies;
  
@Query('movie')
  async getMovieById(
    @Args('id')
    id: string,
  ): Promise<any> 
    const movie = (await db
      .matchNode('movie', 'Movie')
      .where( 'movie.id': id )
      .return([
        
          movie: [ id: 'id', title: 'title', year: 'year' ],
        ,
      ])
      .run<any>()) as any;
if (movie.length === 0) 
      throw new NotFoundException(
        `Movie id '$id' does not exist in database `,
      );
    
return movie[0];
  
@ResolveProperty()
  async actors(@Parent() movie: any) 
    const  id  = movie;
return (await db
      .match([node('actors', 'Actor'), relation('in'), node('movie', 'Movie')])
      .where( 'movie.id': id )
      .return([
        
          actors: [
            
              id: 'id',
              name: 'name',
              born: 'born',
            ,
          ],
        ,
      ])
      .run()) as any;
  

【问题讨论】:

【参考方案1】:

在 neo4j 版本 4 服务器上运行时,我遇到了与 grandSTACK 相同的问题。根据 Will Lyon 的说法,这是由于驱动程序和数据库之间的加密默认值不匹配:https://community.neo4j.com/t/migrating-an-old-grandstack-project-to-neo4j-4/16911/2

所以传递一个配置对象

 encrypted: "ENCRYPTION_OFF"

连接构造函数应该可以解决问题。

【讨论】:

好的,问题是我目前没有使用驱动程序,所以我不完全确定在哪里插入 encrypted: "ENCRYPTION_OFF"。我做了一些试验和错误,但最终抱怨“加密”为不存在类型或类似类型。 驱动程序位于您从“cypher-query-builder”导入的 Connection 类中,快速查看源代码似乎构造函数采用了可选的第三个参数和配置。我不使用 cypher-query-builder,但这可以工作:const db = new Connection(bolt://$HOSTNAME, username: NEO4J_USER, password: NEO4J_PASSWORD, , encrypted: "ENCRYPTION_OFF" ); 您需要在您的凭据之后使用 driverConfig: encrypted: 'ENCRYPTION_OFF', , ,传递另一个对象【参考方案2】:

一定要像这样传递 Config 对象:

var hostname = this.configService.get<string>('NEO4J_URL');
var username = this.configService.get<string>('NEO4J_USERNAME');
var password = this.configService.get<string>('NEO4J_PASSWORD');

db = new Connection(`$hostname`, 
        username: username,
        password: password,
    ,  
        driverConfig:  encrypted: "ENCRYPTION_OFF" 
    );

【讨论】:

以上是关于“在建立安全 TLS 连接之前断开客户端网络套接字” - Neo4j/GraphQL的主要内容,如果未能解决你的问题,请参考以下文章