mvp内粗泄露问题
by Yisroel Yakovson
通过伊斯洛尔·雅科夫森
This article follows two others about creating Full Graph Stacks. Check out How To Build A Cutting Edge Server Now for a conceptual introduction to the approach. Launch Your MVP Server In An Hour guides you through building a stack of development quality. This article explains how to convert that stack to a robust, permanent application.
本文紧跟其他两个有关创建完整图栈的问题。 立即查看如何构建最先进的服务器 ,以对该方法进行概念性介绍。 一小时内启动MVP服务器将引导您构建一整套开发质量。 本文介绍了如何将堆栈转换为健壮的永久性应用程序。
The steps in the second article mirrored the GRANDstack video:
第二篇文章中的步骤反映了GRANDstack视频:
The database is a Neo4j Sandbox
该数据库是Neo4j沙箱
The APIC server runs on Now.
APIC服务器在Now上运行。
That’s enough for an MVP or for the initial prototyping, but you’ll have to move on soon. The biggest initial limitation is the database. The sandbox will live at most ten days.
对于MVP或初始原型来说,这已经足够了,但是您将不得不继续前进。 最大的初始限制是数据库。 沙盒最多可以使用十天。
Even after you spin up a permanent database, Now would make a difficult permanent home. In theory, it would be possible if you didn’t modify your server frequently. You could set up your permanent API with a separate host and alias it to your Now endpoint. The problem is that the Now endpoint changes each time you upload a revision. That means that you have to keep updating your alias.
即使您启动了永久数据库,Now也将成为一个困难的永久家园。 从理论上讲,如果您不经常修改服务器是有可能的。 您可以使用单独的主机设置永久性API,并将其别名为Now端点。 问题在于,每次上载修订时,Now端点都会更改。 这意味着您必须继续更新别名。
Security also poses a challenge. It’s common to create a white list of IPs permitted to access your database and to limit the list to your API server. So if that server IP changes frequently, you have to update the list with each revision. I don’t see a viable way to do that with Now as of this writing. (Please reach out to me if you do!)
安全也带来了挑战。 通常会创建一个允许访问数据库的IP白名单,并将该列表限制为您的API服务器。 因此,如果该服务器IP频繁更改,则必须使用每个修订版更新列表。 在撰写本文时,我还没有一种可行的方法来使用Now。 (如果愿意,请与我联系!)
So the question is, what’s the best approach to solve these limitations?
所以问题是,解决这些局限性的最佳方法是什么?
The truth is, this article has been on hold for a few weeks. The problem was that neo4j-graphql-js was not quite ready to support production. But in the past few weeks, that all changed. The team solved a few fundamental problems:
事实是,本文已搁置了几个星期。 问题在于neo4j-graphql-js尚未准备好支持生产。 但是在过去的几周中,这一切都改变了。 团队解决了一些基本问题:
Middleware became supportable two weeks ago. The team added to the generated reducers support for throwing middleware errors. That enables your server to run general authentication and authorization functionality as middleware.
中间件在两周前开始受支持。 该团队在生成的reducers中添加了对引发中间件错误的支持。 这使您的服务器可以将常规身份验证和授权功能作为中间件运行。
Modification of mutations became possible a week ago. Until then, you were stuck with the generated mutations. Now you can add necessary business logic or side effects.
一周前可以对突变进行修饰。 在此之前,您一直对产生的突变感到困惑。 现在,您可以添加必要的业务逻辑或副作用。
This writing, on August 19, 2018, comes in the midst of many other expected fixes. Of particular interest, the team plans to release some directives to simplify auth. Also, I hope that we will soon see nested mutations. Much of what I write here will soon become outdated. But I’ve decided that it’s worth describing this package now, because it’s already useful. Please post updates or corrections below as comments.
这篇撰写于2018年8月19日的文字来自其他许多预期的修复程序中。 特别感兴趣的是,该团队计划发布一些指令以简化auth。 另外,我希望我们很快会看到嵌套的突变 。 我在这里写的大部分内容很快就会过时。 但是我认为现在值得描述这个软件包,因为它已经很有用了。 请在下面发布更新或更正作为评论。
When you leave the world of sandboxes, you have choices. I think that the general rule is that today most are fine. The important thing is to move forward.
当您离开沙箱世界时,您将有选择。 我认为一般规则是今天大多数情况都很好。 重要的是要前进。
But the three basic steps that I discuss below are probably universal needs. They may be all that you need for your back end.
但是我下面讨论的三个基本步骤可能是普遍需要。 它们可能是您后端所需的全部。
Two introductory observations:
两个介绍性观察:
If you followed the steps in Launch Your MVP Server In An Hour, you have an amazingly small back end. You will need three components: your tiny server app, your database, and an auth service. You don’t even have to store them with the same host.
如果按照“ 在一小时内启动MVP服务器”中的步骤进行操作,则后端将非常小。 您将需要三个组件:小型服务器应用程序,数据库和身份验证服务。 您甚至不必将它们存储在同一主机上。
Set up Auth
设置身份验证
Spin your Database
旋转数据库
Create Your Server
创建您的服务器
Every project’s auth needs are different, but some basics have emerged. You need two things:
每个项目的身份验证需求都是不同的,但是已经出现了一些基础知识。 您需要两件事:
The preferred way to handle Auth is through middleware or directives. As of the current writing, auth is not included in the GRANDstack starter.
处理Auth的首选方法是通过中间件或指令。 截至目前,auth未包含在GRANDstack启动器中。
The server used in api/src/index.jx
in the starter package is currently ApolloServer
. But you can replace that with graphalExpress
from apollo-server-express
.
入门包中api/src/index.jx
中使用的服务器当前是ApolloServer
。 但是您可以使用apollo-server-express
graphalExpress
替换它。
You will have to change 2 files:
您将必须更改2个文件:
api/src/index.js
api/src/index.js
api/package.json
api/package.json
You should also add an auth.js
file.
您还应该添加一个auth.js
文件。
Here’s a version of index.js
that currently works with middleware:
这是当前可与中间件一起使用的index.js
版本:
import express from 'express';import { graphqlExpress, graphiqlExpress } from 'apollo-server-express';import cors from 'cors';import { makeExecutableSchema } from 'graphql-tools'import expressPlayground from 'graphql-playground-middleware-express';import bodyParser from 'body-parser';require('dotenv').config();import { v1 as neo4j } from "neo4j-driver";import { augmentSchema } from "neo4j-graphql-js";import { typeDefs, resolvers } from "./graphql-schema";import { authenticateUser, authorize } from './auth';// augmentSchema will add autogenerated mutations based on types in schemaconst schema = makeExecutableSchema({ typeDefs, resolvers});const augmentedSchema = augmentSchema(schema);const driver = neo4j.driver( process.env.NEO4J_URI, neo4j.auth.basic( process.env.NEO4J_USER, process.env.NEO4J_PASSWORD ));const app = express();app.use(bodyParser.json()); // support json encoded bodiesapp.use(cors());app.use('/graphql i apollo-server-expressql', graphiqlExpress({ endpointURL: '/graphql'}));app.get('/', expressPlayground({ endpoint: '/graphql' }));// app.use('/', authenticateUser, authorize);app.use('/graphql', bodyParser.json(), graphqlExpress(req => { return { context: { auth: req.auth, driver }, endpointURL: '/graphql', schema: augmentedSchema }}));app.listen(process.env.GRAPHQL_LISTEN_PORT, '0.0.0.0');console.log(`GraphQL Playground at ${process.env.GRAPHQL_LISTEN_PORT}`);
Note that:
注意:
The project.json file must contain the proper dependencies. As of this writing, here are the versions I’m using:
project.json文件必须包含适当的依赖项。 在撰写本文时,这是我正在使用的版本:
{ "name": "grand-stack-express", "version": "0.0.1", "description": "API app for GRANDstack with express", "main": "src/index.js", "license": "MIT", "dependencies": { "apollo-server-express": "^1.3.6", "babel-cli": "^6.26.0", "babel-core": "^6.26.3", "babel-polyfill": "^6.26.0", "babel-preset-env": "^1.7.0", "babel-preset-stage-0": "^6.24.1", "babel-watch": "^2.0.7", "body-parser": "^1.18.3", "cors": "^2.8.4", "dotenv": "^6.0.0", "express": "^4.16.3", "express-graphql": "^0.6.12", "graphql-playground-middleware-express": "^1.7.1", "graphql-tag": "^2.9.2", "graphql-tools": "^3.0.4", "neo4j-driver": "^1.6.3", "neo4j-graphql-js": "^0.1.32", "node-fetch": "^2.1.2", "nodemon": "^1.17.5" }, "resolutions": { "neo4j-graphql-js/graphql": "v14.0.0-rc.2" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "babel-watch --exec babel-node --presets env,stage-0 src/index.js", "start": "nodemon --exec babel-node --presets env,stage-0 src/index.js" }, "devDependencies": { "nodemon": "^1.17.5" }}
Here’s a starter auth.js file to add to your project and complete:
这是要添加到您的项目并完成的入门auth.js文件:
import gql from 'graphql-tag'import { v1 as neo4j } from 'neo4j-driver';import { INSPECT_MAX_BYTES } from 'buffer';require('dotenv').config();const driver = neo4j.driver( process.env.NEO4J_URI, neo4j.auth.basic( process.env.NEO4J_USER, process.env.NEO4J_PASSWORD ));const resolveUser = () => { //a placeholder return 0;}/* * middleware functions follow */export const authenticateUser = async (req, res, next) => { req.auth={}; try { const response = await resolveUser(); req.auth.user=response } catch(err) { req.error=err.message } next();}export const authorize = async (req, res, next) => { if (req.error) { console.log(req.error); next(); return; } // placeholder, allows every authenticated request next();}
start by committing your old version to git and probably creating a new branch. git add .
then git commit -m "works without auth"
and then git checkout -b auth
. You will then see a response of
首先将旧版本提交到git并可能创建一个新分支。 git add .
然后git commit -m "works without auth"
,然后git checkout -b auth
。 然后,您将看到对
start by committing your old version to git and probably creating a new branch. git add .
then git commit -m "works without auth"
and then git checkout -b auth
. You will then see a response of Switched to a new branch ‘auth’
首先将旧版本提交到git并可能创建一个新分支。 git add .
然后git commit -m "works without auth"
,然后git checkout -b auth
。 然后,您将看到Switched to a new branch 'auth'
的响应
replace your api/src/index.js
and api/project.json
files with the versions above, and add the auth.js
file to api/src
.
将api/src/index.js
和api/project.json
文件替换为上述版本,然后将auth.js
文件添加到api/src
。
move your current node_modules: mv node_modules node_modules.old
移动当前的node_modules: mv node_modules node_modules.old
run npm install
again, then npm start
. Make sure that it works by running a query.
再次运行npm install
,然后再npm start
。 通过运行查询确保它可以工作。
You can fill in the details based on the SDK for whatever auth software you use.
您可以根据使用的任何身份验证软件的SDK填写详细信息。
You may have to study up on using async/await functions in an express app, but it’s not too difficult to learn.
您可能需要研究在快速应用程序中使用异步/等待功能 ,但是学习起来并不难。
Uncomment the line app.use(‘/’, authenticateUser, authorize);
in index.js
.
取消注释行app.use('/', authenticateUser, authorize);
在index.js
。
Install the proper Node js SDK for your Authentication service. Then add the needed code and rewrite the function authenticateUser
in auth.js
to call it. Remember to set req.error
to an appropriate error message when authentication fails.
为您的身份验证服务安装正确的Node js SDK。 然后添加所需的代码,并在auth.js
重写函数authenticateUser
进行调用。 当身份验证失败时,请记住将req.error
设置为适当的错误消息。
The file auth.js
includes a database driver. The driver supports querying to determine a user’s access rights to specific data. For instance, your database could store read/write privileges for data. Whenever a request fails your test, you can specify what failed by setting req.error
. The neo4jgraphql
resolver function will return the error message.
文件auth.js
包含数据库驱动程序。 该驱动程序支持查询以确定用户对特定数据的访问权限。 例如,您的数据库可以存储数据的读/写特权。 每当请求测试失败时,您都可以通过设置req.error
来指定失败的req.error
。 neo4jgraphql
解析器函数将返回错误消息。
Note that you can add more functions to the middleware. For instance, you might add a check whether the current user is fully paid.
请注意,您可以向中间件添加更多功能。 例如,您可以添加检查当前用户是否已全额付款。
The call to augmentSchema
in the index.js
file generates the mutations in your schema. As stated above, a recent enhancement lets you add mutations. You can also overwrite the generated ones.
在index.js
文件中对augmentSchema
的调用会在您的模式中生成突变。 如上所述,最近的增强使您可以添加突变。 您也可以覆盖生成的内容。
One simple way is with the @cypher directive in your mutation declaration:
一种简单的方法是在您的突变声明中使用@cypher指令:
type Mutation { UpdateFoo(id: ID, name: String): Foo @cypher(statement:”MATCH (f:Foo {id: $id}) SET f.name = $name”}
Then, for the resolver just use neo4jgraphql
:
然后,对于解析器,只需使用neo4jgraphql
:
Mutation: { UpdateFoo: neo4jgraphql}
You have some options. First, there are some hosting services. I wasn’t so impressed, because it’s not that hard to create a database server yourself. But, the cost is a drop in the bucket compared to your team’s time. If you pay a few hundred dollars a month to get something up and running, and you have no worries, you could do a lot worse.
您有一些选择。 首先,有一些托管服务 。 我没有那么印象深刻,因为自己创建数据库服务器并不难。 但是,与您团队的时间相比,成本简直是九牛一毛。 如果您每个月花费几百美元来启动和运行某项产品,并且没有后顾之忧,则可能会做得更糟。
I decided to spin up an AWS EC2 instance instead. I’m going to write what I did there.
我决定改为启动一个AWS EC2实例。 我要写在那里做的事。
Do the steps (until the last one) here. Make sure to save your key file, as you’ll need it for setting up APOC.
在这里执行步骤(直到最后一个步骤)。 确保保存密钥文件,因为设置APOC时将需要它。
Then you need to go to the page, log in and change the password. But which port to go to and what password might not be the same as there. For my AMI, the password was “neo4j” (like the user name). I had to go to https://[IP]:7473/browser/ (not http as in the example given on the page, and not 7434).
然后,您需要转到该页面,登录并更改密码。 但是,要转到哪个端口,什么密码可能与那里的密码不同。 对于我的AMI,密码为“ neo4j”(类似于用户名)。 我必须转到https:// [IP]:7473 / browser / (不是页面上给出的示例中的http,而不是7434)。
To use @cypher
directives, or any of the APOC functions, you’ll have to to install the APOC jar file on the server itself. You’ll need to ssh in to your database server. As of 2 months ago, it wasn’t included in the AMIs.
要使用@cypher
指令或任何APOC函数,您必须在服务器本身上安装APOC jar文件。 您需要ssh进入数据库服务器。 截至2个月前,它尚未包含在AMI中。
You’ll need to use the command shown at Hosting Neo4j on EC2 on AWS: ssh -i $KEY_NAME.pem ubuntu@[PublicDnsName]
您需要使用在AWS上的EC2上托管Neo4j上显示的命令: ssh -i $KEY_NAME.pem ubuntu@[PublicDnsName]
You’ll have to add the jar file to the neo4j plugins directory. Follow the manual instructions to find the latest release and figure out where to insert it.
您必须将jar文件添加到neo4j插件目录中。 请按照手册中的说明查找最新版本,并找出在何处插入。
You also need to find your neo4j.conf file and insert into it permission to call the functions. The following works: dbms.security.procedures.unrestricted=apoc.*
您还需要找到neo4j.conf文件,并在其中插入调用这些函数的权限。 以下工作: dbms.security.procedures.unrestricted=apoc.*
Then you’ll have to restart: sudo systemctl restart neo4j.
然后,您必须重新启动: sudo systemctl restart neo4j.
You can deploy on any system that supports a NODE js app. I used AWS Elastic Beanstalk:
您可以在支持NODE js应用程序的任何系统上进行部署。 我使用了AWS Elastic Beanstalk :
Run the command zip -r api.zip . -x node_modules/**\*
in the api
directory. That creates a zip without the directory itself and without the node_modules.
运行命令zip -r api.zip . -x node_modules/**\*
api
目录中的zip -r api.zip . -x node_modules/**\*
。 这将创建一个没有目录本身且没有node_modules的zip。
Go to AWS Elastic Beanstalk in the console and make sure you’re in your region of choice.
在控制台中转到AWS Elastic Beanstalk ,并确保您位于选择的区域中。
If you can get to the welcome page, I find it the easiest. You click on Get Started, and follow the instructions. They set me up right away with what I needed. You just upload the file that you zipped above.
如果可以访问欢迎页面,我觉得这是最简单的。 您单击开始 ,然后按照说明进行操作。 他们立即根据我的需要设置了我。 您只需上传压缩过的文件即可。
nder Configuration for the Elastic Beanstalk environment, go to Modify Software. Enter Container Options, and set Node Command to npm start
.
在“ Elastic Beanstalk环境”的“ 配置”下 ,转到“ 修改软件” 。 输入Container Options ,然后将Node Command设置为npm start
。
After about 10 minutes, it’s ready. You can click on the endpoint URL to see it.
大约10分钟后,它准备就绪。 您可以单击端点URL来查看它。
If you’ve followed this far, congratulations. You know more about how to build a full graph stack than many seasoned back end designers.
如果您遵循了这一步,那么恭喜。 与许多经验丰富的后端设计师相比,您对如何构建完整的图形堆栈了解更多。
The process described in these articles might take an hour for someone who has done them a few times. For anyone else, these articles hopefully minimize the extra time to research. The development time should fall even more as these tools improve.
这些文章中描述的过程可能需要花费一个小时来完成几次。 对于其他任何人,这些文章都希望将额外的研究时间减至最少。 随着这些工具的改进,开发时间应进一步减少。
But simplicity and ease are just one benefit. The full graph stack is also technologically sound.
但是,简单和轻松只是好处之一。 完整的图形堆栈在技术上也很合理。
Let us work together to keep this technology moving. Please leave comments or reach out with other improvements. Good luck with your own projects!
让我们共同努力,使这项技术不断发展。 请发表评论或进行其他改进。 祝您自己的项目好运!
翻译自: https://www.freecodecamp.org/news/making-your-full-graph-stack-production-quality-ec231a938551/
mvp内粗泄露问题