返回

开发人员使用Node.js创建安全的GraphQL API的全面指南

前端

如今,几乎每个解决方案都需要某种应用程序编程接口(API)。即使您只使用社交网络(如Facebook或Instagram),也仍然会用到使用API​​的前端。如果您感到好奇,您会发现几乎每个应用程序都有一个公共API,允许应用程序之间进行通信。

GraphQL是一种用于API的查询语言,它允许客户端请求所需的确切数据。GraphQL API本质上是安全的,因为它们只公开您明确定义的字段。但是,为了创建完全安全的GraphQL API,您需要考虑一些额外的安全措施。

在本文中,我们将引导您完成使用Node.js创建安全的GraphQL API的各个步骤。我们将介绍身份验证和授权、跨域资源共享(CORS)以及如何使用JSON Web令牌(JWT)来保护您的API。

先决条件

  • Node.js >= 8.0.0
  • npm >= 5.0.0
  • GraphQL库(例如graphql、apollo-server)
  • JWT库(例如jsonwebtoken)
  • CORS库(例如cors)

1. 设置Node.js项目

首先,我们需要创建一个新的Node.js项目。您可以使用以下命令来做到这一点:

mkdir my-graphql-api
cd my-graphql-api
npm init -y

这将在当前目录中创建一个新的Node.js项目,并安装必要的依赖项。

2. 安装GraphQL库

接下来,我们需要安装一个GraphQL库。在本文中,我们将使用apollo-server库。您可以使用以下命令来安装它:

npm install apollo-server --save

3. 创建GraphQL模式

接下来,我们需要创建一个GraphQL模式。模式定义了API的结构,包括可用字段和类型。

在项目目录中,创建一个名为schema.graphql的文件。我们将使用以下模式:

type Query {
  users: [User]
  user(id: ID!): User
}

type User {
  id: ID!
  name: String!
  email: String!
}

此模式定义了两个查询:users和user。users查询返回所有用户列表,而user查询返回特定ID的用户。它还定义了一个名为User的类型,它具有id、name和email字段。

4. 创建GraphQL解析器

接下来,我们需要为模式中的每个查询创建解析器。解析器是获取数据并将其返回给客户端的函数。

在项目目录中,创建一个名为resolvers.js的文件。我们将使用以下解析器:

const users = [
  { id: '1', name: 'John Doe', email: 'johndoe@example.com' },
  { id: '2', name: 'Jane Doe', email: 'janedoe@example.com' },
];

const resolvers = {
  Query: {
    users: () => users,
    user: (_, { id }) => users.find(user => user.id === id),
  },
};

这些解析器使用了一个名为users的硬编码数组。在实际应用程序中,您将从数据库或其他数据源获取数据。

5. 创建GraphQL服务器

接下来,我们需要创建一个GraphQL服务器。服务器将侦听请求并返回响应。

在项目目录中,创建一个名为server.js的文件。我们将使用以下代码:

const { ApolloServer } = require('apollo-server');
const { schema, resolvers } = require('./schema');

const server = new ApolloServer({
  schema,
  resolvers,
});

server.listen().then(({ url }) => {
  console.log(`🚀  Server ready at ${url}`);
});

此代码创建了一个新的ApolloServer实例,并使用schema和resolvers参数对其进行配置。然后它调用listen()方法来启动服务器。

6. 添加身份验证和授权

现在我们的GraphQL API已经运行,但它还没有任何安全措施。接下来,我们将添加身份验证和授权,以便只有授权用户才能访问API。

我们将使用jsonwebtoken库来生成和验证JWT。JWT是用于在两个 parties 之间安全地传输信息的小型、自包含的令牌。

在项目目录中,创建一个名为auth.js的文件。我们将使用以下代码:

const jwt = require('jsonwebtoken');

const secret = 'my-secret';

const generateAccessToken = (user) => {
  return jwt.sign({ id: user.id, name: user.name }, secret, { expiresIn: '1h' });
};

const verifyAccessToken = (token) => {
  return jwt.verify(token, secret);
};

此代码创建了一个名为generateAccessToken的函数,用于生成JWT,以及一个名为verifyAccessToken的函数,用于验证JWT。

接下来,我们需要在GraphQL服务器中启用身份验证和授权。在server.js文件中,添加以下代码:

const { ApolloServer } = require('apollo-server');
const { schema, resolvers } = require('./schema');
const { generateAccessToken, verifyAccessToken } = require('./auth');

const server = new ApolloServer({
  schema,
  resolvers,
  context: ({ req }) => {
    const token = req.headers['authorization'];
    if (!token) {
      throw new Error('No token provided.');
    }
    const decoded = verifyAccessToken(token.replace('Bearer ', ''));
    return { decoded };
  },
});

server.listen().then(({ url }) => {
  console.log(`🚀  Server ready at ${url}`);
});

此代码使用context选项为GraphQL服务器启用身份验证和授权。context选项是一个函数,它接收一个包含请求对象的