Создание простого REST API с помощью Node и OAuth 2.0

Node.js сервер API Программа перевода самородков

JavaScript повсюду в Интернете — почти каждая веб-страница содержит немного JavaScript, и даже без JavaScript в вашем браузере может быть какое-то расширение, которое вставляет код JavaScript на страницу. До сих пор эти вещи были неизбежны.

JavaScript также можно использовать для чего угодно вне контекста браузера, от размещения веб-сервера до управления радиоуправляемой машиной или запуска полноценной операционной системы. Иногда вам нужна группа серверов, которые могут взаимодействовать друг с другом, будь то в локальной сети или в Интернете.

Сегодня я покажу вам, как создать REST API с помощью Node.js и защитить его с помощью OAuth 2.0 для блокировки нежелательных запросов. REST API изобилуют в Интернете, но без правильных инструментов требуется много шаблонного кода. Я покажу вам, как использовать некоторые удивительные инструменты, которые могут легко реализовать поток аутентификации на стороне клиента, который безопасно соединяет две машины без пользовательского контекста.

Создайте свой Node-сервер

использоватьЭкспресс-библиотека JavaScriptНастроить веб-сервер в Node очень просто. Создайте новую папку, содержащую сервер.

$ mkdir rest-api

Узел используетpackage.jsonдля управления зависимостями и определения вашего проекта. Мы используемnpm initдля создания нового файла. Эта команда задаст вам несколько вопросов, помогая вам инициализировать ваш проект. Теперь вы можете использоватьСтандартный JSдля обеспечения соблюдения стандартов кодирования и использования их в качестве тестов.

$ cd rest-api

$ npm init
这个实用工具将引导你创建 package.json 文件。
它只涵盖最常见的项目,并试图猜测合理的默认值。

请参阅 `npm help json` 来获取关于这些字段的确切文档以及它们所做的事情。

使用 `npm install <pkg>` 命令来安装一个 npm 依赖,并将其保存在 package.json 文件中。

Press ^C at any time to quit.
package name: (rest-api)
version: (1.0.0)
description: A parts catalog
entry point: (index.js)
test command: standard
git repository:
keywords:
author:
license: (ISC)
About to write to /Users/Braden/code/rest-api/package.json:

{
  "name": "rest-api",
  "version": "1.0.0",
  "description": "A parts catalog",
  "main": "index.js",
  "scripts": {
    "test": "standard"
  },
  "author": "",
  "license": "ISC"
}


Is this OK? (yes)

Конечная точка входа по умолчаниюindex.js, поэтому вы должны создатьindex.jsдокумент. Приведенный ниже код даст вам очень простой сервер, который по умолчанию ничего не делает, кроме прослушивания порта 3000.

index.js

const express = require('express')
const bodyParser = require('body-parser')
const { promisify } = require('util')

const app = express()
app.use(bodyParser.json())

const startServer = async () => {
  const port = process.env.SERVER_PORT || 3000
  await promisify(app.listen).bind(app)(port)
  console.log(`Listening on port ${port}`)
}

startServer()

utilизpromisifyФункции позволяют вам принимать функцию, которая ожидает обратный вызов, а затем возвращает обещание, новый стандарт работы с асинхронным кодом. Это также позволяет нам использовать относительно новыйasync/awaitсинтаксис и сделать наш код намного красивее.

Для того, чтобы заставить его работать, вам нужно загрузить файл, который вы импортировали в шапке файлаrequireполагаться. использоватьnpm installустановить их. Это автоматически сохранит некоторые метаданные в вашемpackage.jsonфайлы и скачать их локальноnode_modulesв файле.

Уведомление: вы никогда не должны фиксировать исходный кодnode_modules, потому что управление исходным кодом имеет тенденцию быстро раздуваться, иpackage-lock.jsonФайлы будут отслеживать точную версию, которую вы используете, и если вы установите ее на другой компьютер, они получат тот же код.

$ npm install express@4.16.3 util@0.11.0

Для быстрого анализа установитеstandardкак зависимость разработчика, затем запустите его, чтобы убедиться, что ваш код соответствует номиналу.

$ npm install --save-dev standard@11.0.1
$ npm test

> rest-api@1.0.0 test /Users/bmk/code/okta/apps/rest-api
> standard

Если все пойдет хорошо, в> standardПосле строки вы не должны видеть никакого вывода. Если есть ошибка, это может выглядеть так:

$ npm test

> rest-api@1.0.0 test /Users/bmk/code/okta/apps/rest-api
> standard

standard: Use JavaScript Standard Style (https://standardjs.com)
standard: Run `standard --fix` to automatically fix some problems.
  /Users/Braden/code/rest-api/index.js:3:7: Expected consistent spacing
  /Users/Braden/code/rest-api/index.js:3:18: Unexpected trailing comma.
  /Users/Braden/code/rest-api/index.js:3:18: A space is required after ','.
  /Users/Braden/code/rest-api/index.js:3:38: Extra semicolon.
npm ERR! Test failed.  See above for more details.

Теперь, когда ваш код готов и необходимые зависимости загружены, вы можете использоватьnode .Сервер работает. (.означает посмотреть в переднем каталоге, а затем проверитьpackage.jsonфайл, чтобы определить, в каком каталоге используется основной файлindex.js):

$ node .

Listening on port 3000

Чтобы проверить его работу, вы можете использоватьcurlЗаказ. Конечной точки нет, поэтому Express вернет ошибку:

$ curl localhost:3000 -i
HTTP/1.1 404 Not Found
X-Powered-By: Express
Content-Security-Policy: default-src 'self'
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8
Content-Length: 139
Date: Thu, 16 Aug 2018 01:34:53 GMT
Connection: keep-alive

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /</pre>
</body>
</html>

Даже если он выдает ошибку, это очень хорошая ситуация. Вы не настроили конечные точки, поэтому Express вернет только ошибку 404. Если ваш сервер вообще не работает, вы получите такие ошибки, как:

$ curl localhost:3000 -i
curl: (7) Failed to connect to localhost port 3000: Connection refused

Создайте свой REST API с помощью Express, Sequelize и Epilogue

Теперь у вас есть работающий сервер Express, и вы можете добавить REST API. На самом деле это намного проще, чем вы думаете. Самый простой способ, который я видел, это использоватьSequelizeдля определения полей базы данных,EpilogueСоздавайте конечные точки REST API практически без шаблонов.

Вам нужно добавить эти зависимости в свой проект. Sequelize также должен знать, как взаимодействовать с базой данных. Сейчас используется SQLite, потому что он помогает нам быстро приступить к работе.

npm install sequelize@4.38.0 epilogue@0.7.1 sqlite3@4.0.2

Создайте новый файл со следующим кодомdatabase.js. Ниже я подробно объясняю каждую часть.

database.js

const Sequelize = require('sequelize')
const epilogue = require('epilogue')

const database = new Sequelize({
  dialect: 'sqlite',
  storage: './test.sqlite',
  operatorsAliases: false
})

const Part = database.define('parts', {
  partNumber: Sequelize.STRING,
  modelNumber: Sequelize.STRING,
  name: Sequelize.STRING,
  description: Sequelize.TEXT
})

const initializeDatabase = async (app) => {
  epilogue.initialize({ app, sequelize: database })

  epilogue.resource({
    model: Part,
    endpoints: ['/parts', '/parts/:id']
  })

  await database.sync()
}

module.exports = initializeDatabase

Теперь вам просто нужно импортировать эти файлы в основное приложение и запустить функцию инициализации. В твоемindex.jsДобавьте в файл следующее.

index.js

@@ -2,10 +2,14 @@ const express = require('express')
 const bodyParser = require('body-parser')
 const { promisify } = require('util')

+const initializeDatabase = require('./database')
+
 const app = express()
 app.use(bodyParser.json())

 const startServer = async () => {
+  await initializeDatabase(app)
+
   const port = process.env.SERVER_PORT || 3000
   await promisify(app.listen).bind(app)(port)
   console.log(`Listening on port ${port}`)

Теперь вы можете проверить наличие синтаксических ошибок, и если все в порядке, вы можете запустить приложение:

$ npm test && node .

> rest-api@1.0.0 test /Users/bmk/code/okta/apps/rest-api
> standard

Executing (default): CREATE TABLE IF NOT EXISTS `parts` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `partNumber` VARCHAR(255), `modelNu
mber` VARCHAR(255), `name` VARCHAR(255), `description` TEXT, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL);
Executing (default): PRAGMA INDEX_LIST(`parts`)
Listening on port 3000

В другом терминале вы можете проверить, что он действительно работает (я используюjson CLIчтобы отформатировать ответ JSON, используйтеnpm install --global jsonдля глобальной установки):

$ curl localhost:3000/parts
[]

$ curl localhost:3000/parts -X POST -d '{
  "partNumber": "abc-123",
  "modelNumber": "xyz-789",
  "name": "Alphabet Soup",
  "description": "Soup with letters and numbers in it"
}' -H 'content-type: application/json' -s0 | json
{
  "id": 1,
  "partNumber": "abc-123",
  "modelNumber": "xyz-789",
  "name": "Alphabet Soup",
  "description": "Soup with letters and numbers in it",
  "updatedAt": "2018-08-16T02:22:09.446Z",
  "createdAt": "2018-08-16T02:22:09.446Z"
}

$ curl localhost:3000/parts -s0 | json
[
  {
    "id": 1,
    "partNumber": "abc-123",
    "modelNumber": "xyz-789",
    "name": "Alphabet Soup",
    "description": "Soup with letters and numbers in it",
    "createdAt": "2018-08-16T02:22:09.446Z",
    "updatedAt": "2018-08-16T02:22:09.446Z"
  }
]

Что случилось с этим?

Если вы следовали нашим шагам раньше, вы можете пропустить эту часть, так как это объяснение, которое я обещал дать.

SequelizeФункция создает базу данных. Именно здесь должны использоваться детали конфигурации, такие как операторы SQL. Теперь используйте SQLite, чтобы быстро приступить к работе.

const database = new Sequelize({
  dialect: 'sqlite',
  storage: './test.sqlite',
  operatorsAliases: false
})

После создания базы данных вы можете использовать для каждой таблицыdatabase.defineопределить его таблицу. Создать с некоторыми полезными полями, называемымиpartsСтол приходит для отслеживания деталей. По умолчанию Sequelize также автоматически создает и обновляет при создании и обновленииid,createdAtиupdatedAtполе.

const Part = database.define('parts', {
  partNumber: Sequelize.STRING,
  modelNumber: Sequelize.STRING,
  name: Sequelize.STRING,
  description: Sequelize.TEXT
})

Эпилог Для добавления конечных точек будет запрашиваться экспресс-доставкаappразрешение на доступ. ноappопределяется в другом файле. Один из способов справиться с этим — экспортировать функцию, которая берет приложение и что-то с ним делает. Когда мы импортируем этот скрипт в другой файл, вы можете запустить его какinitializeDatabase(app)запускай так же.

Эпилог нужно использовать вместеappиdatabaseдля инициализации. Soften определяет конечные точки REST, которые вам необходимо использовать.resourceфункция будет включатьGET,POST,PUTиDELETEОкончания глаголов, большинство из которых автоматизированы.

Чтобы фактически создать базу данных, вам нужно запустить промис, который возвращает промис.database.sync(). Прежде чем запускать сервер, необходимо дождаться его завершения.

module.exportsсмыслinitializeDatabaseФункция может быть импортирована из другой функции.

const initializeDatabase = async (app) => {
  epilogue.initialize({ app, sequelize: database })

  epilogue.resource({
    model: Part,
    endpoints: ['/parts', '/parts/:id']
  })

  await database.sync()
}

module.exports = initializeDatabase

Защитите свой Node + Express REST API с помощью OAuth 2.0

Теперь, когда у вас запущен и работает REST API, представьте, что вы хотите, чтобы конкретное приложение использовало этот API из удаленного места. Если вы сохраните его как есть в Интернете, любой может добавлять, изменять или удалять части по своему желанию.

Чтобы избежать этого, вы можете использовать учетные данные клиента OAuth 2.0. Это способ для двух серверов общаться друг с другом без контекста. Оба сервера должны заранее согласиться на использование стороннего сервера авторизации. Предположим, что есть два сервера, A и B, и сервер доступа. Сервер A размещает REST API, а сервер B хочет получить доступ к API.

  • Сервер B отправляет закрытый ключ на сервер авторизации, чтобы подтвердить свою личность и запросить временный токен.
  • Сервер B будет использовать REST API, как обычно, но отправит токен вместе с запросом.
  • Сервер A запрашивает некоторые метаданные с сервера авторизации, которые можно использовать для проверки токена.
  • Сервер A проверяет запрос сервера B.
    • Если он действителен, будет отправлен успешный ответ, и сервер B будет работать нормально.
    • Если токен недействителен, будет отправлено сообщение об ошибке, и конфиденциальная информация не будет раскрыта.

Создайте сервер авторизации

Здесь в игру вступает OKta. OKta может выступать в роли сервера, позволяющего защитить ваши данные. Вы можете спросить себя: «Почему OKta?» Хорошо, это здорово для создания REST-приложений, но созданиеБезопасностьприложение будет еще круче. Для этого вам необходимо добавить аутентификацию, чтобы пользователи должны были войти в систему перед просмотром/изменением групп. В Okta наша цель — обеспечить, чтобыУправление идентификациейПроще, безопаснее и масштабируемее, чем то, что вы использовали в прошлом. Okta — это облачный сервис, который позволяет разработчикам создавать, редактировать и безопасно хранить учетные записи пользователей и данные учетных записей пользователей, а также связывать их с одним или несколькими приложениями. Наш API позволяет:

Если у вас еще нет учетной записи,Вы можете зарегистрировать постоянную бесплатную учетную запись разработчика,Давайте начнем!

После создания учетной записи войдите в консоль разработчика, перейдите кAPI, затем перейдите кAuthorization ServersТаб. нажмитеdefaultссылка на сервер.

из этогоSettingsвкладка, копироватьIssuerполе. Вам нужно хранить его там, где ваше приложение Node может его прочитать. В вашем проекте создайте файл с именем.envфайл следующим образом:

.env

ISSUER=https://{yourOktaDomain}/oauth2/default

ISSUERЗначение должно быть страницей настроекIssuer URIзначение поля.

高亮 issuer URL。

Уведомление: Общее правило заключается в том, что вы не должны ставить.envФайлы хранятся в системе контроля версий. Это позволяет нескольким проектам использовать один и тот же исходный код одновременно, вместо того, чтобы требовать отдельных ветвей. Это гарантирует, что ваша информация о безопасности никогда не станет общедоступной (особенно если вы выпускаете свой код с открытым исходным кодом).

Далее перейдите кScopesменю. нажмитеAdd Scopeкнопку и создайте область для REST API. Вам нужно имя (например,parts_manager), и описание, если хотите.

添加范围的截图

Вы также должны добавить масштаб к своему.envфайл, чтобы ваш код мог получить к нему доступ.

.env

ISSUER=https://{yourOktaDomain}/oauth2/default
SCOPE=parts_manager

Теперь вам нужно создать клиент. перейдите кApplications, затем нажмитеAdd Application. выберитеService, затем нажмитеNext. Введите имя службы (например,Parts Manager), а затем нажмитеDone.

Это приведет вас к странице учетных данных конкретного клиента. Это учетные данные, которые необходимы серверу B (серверу, который будет использовать REST API) для аутентификации. В этом примере клиентский и серверный код находятся в одном репозитории, поэтому добавьте эти данные в свой.envв файле. Пожалуйста, убедитесь, что{yourClientId}и{yourClientSecret}Замените значением с этой страницы.

CLIENT_ID={yourClientId}
CLIENT_SECRET={yourClientSecret}

Создайте промежуточное ПО для проверки токенов в Express

В Express вы можете добавить промежуточное ПО, которое будет запускаться перед каждой конечной точкой. Затем вы можете добавить метаданные, установить заголовки, зарегистрировать некоторую информацию и даже отменить запрос досрочно и отправить сообщение об ошибке. В этом примере вам нужно создать промежуточное ПО для проверки токена, отправленного клиентом. Если токен действителен, он будет доставлен в REST API и будет возвращен соответствующий ответ. Если токен недействителен, он ответит сообщением об ошибке, чтобы только авторизованные машины могли получить к нему доступ.

Для проверки токена вы можете использовать промежуточное ПО OKta. Вам также нуженdotenvинструмент для загрузки переменных среды:

npm install dotenv@6.0.0 @okta/jwt-verifier@0.0.12

Теперь создайте файл с именемauth.jsфайл, который может экспортировать промежуточное ПО:

auth.js

const OktaJwtVerifier = require('@okta/jwt-verifier')

const oktaJwtVerifier = new OktaJwtVerifier({ issuer: process.env.ISSUER })

module.exports = async (req, res, next) => {
  try {
    const { authorization } = req.headers
    if (!authorization) throw new Error('You must send an Authorization header')

    const [authType, token] = authorization.trim().split(' ')
    if (authType !== 'Bearer') throw new Error('Expected a Bearer token')

    const { claims } = await oktaJwtVerifier.verifyAccessToken(token)
    if (!claims.scp.includes(process.env.SCOPE)) {
      throw new Error('Could not verify the proper scope')
    }
    next()
  } catch (error) {
    next(error.message)
  }
}

Сначала функция проверяетauthorizationзаголовок присутствует в запросе, а затем выдает ошибку. Если он существует, он должен выглядеть такBearer {token}{token}ЯвляетсяJWTнить. Если заголовок не начинается сBearerзапускается, выдает другую ошибку. Затем мы отправляем токен наВалидатор Okta JWTдля проверки токена. Если токен недействителен, валидатор JWT выдаст ошибку, в противном случае он вернет объект с некоторой информацией. Затем вы можете убедиться, что запрос содержит ожидаемый диапазон.

Если все пойдет хорошо, он будет вызван без аргументовnext()функция, которая скажет Express перейти к следующей функции в цепочке (другое промежуточное ПО или конечная точка). Если вы передаете строку вnextфункция, Express рассматривает ее как ошибку, которая будет передана обратно клиенту и не будет продолжена в цепочке.

Вам все еще нужно импортировать эту функцию и добавить ее в приложение как промежуточное ПО. Вам также необходимо загрузить в верхней части индексного файлаdotenv, Чтобы убедиться, что.envпеременные окружения в вашем приложении. правильноindex.jsВнесите следующие изменения:

index.js

@@ -1,11 +1,14 @@
+require('dotenv').config()
 const express = require('express')
 const bodyParser = require('body-parser')
 const { promisify } = require('util')

+const authMiddleware = require('./auth')
 const initializeDatabase = require('./database')

 const app = express()
 app.use(bodyParser.json())
+app.use(authMiddleware)

 const startServer = async () => {
   await initializeDatabase(app)

Если тестовый запрос заблокирован правильно, попробуйте запустить его снова...

$ npm test && node .

Затем в другом терминале запустите несколькоcurlкоманда для проверки:

  1. Присутствует ли заголовок авторизации в запросе
$ curl localhost:3000/parts
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>You must send an Authorization header</pre>
</body>
</html>
  1. Есть ли токен Bearer в заголовке запроса на авторизацию
$ curl localhost:3000/parts -H 'Authorization: Basic asdf:1234'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Expected a Bearer token</pre>
</body>
</html>
  1. Является ли токен Bearer действительным?
$ curl localhost:3000/parts -H 'Authorization: Bearer asdf'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Jwt cannot be parsed</pre>
</body>
</html>

Создайте тестовый клиент в Node.

Теперь вы заблокировали доступ к приложению для всех, у кого нет действительного токена, но как получить токен и использовать его? Я покажу вам, как написать простой клиент на Node, который также поможет вам проверить, работает ли действительный токен.

npm install btoa@1.2.1 request-promise@4.2.2

client.js

require('dotenv').config()
const request = require('request-promise')
const btoa = require('btoa')

const { ISSUER, CLIENT_ID, CLIENT_SECRET, SCOPE } = process.env

const [,, uri, method, body] = process.argv
if (!uri) {
  console.log('Usage: node client {url} [{method}] [{jsonData}]')
  process.exit(1)
}

const sendAPIRequest = async () => {
  const token = btoa(`${CLIENT_ID}:${CLIENT_SECRET}`)
  try {
    const auth = await request({
      uri: `${ISSUER}/v1/token`,
      json: true,
      method: 'POST',
      headers: {
        authorization: `Basic ${token}`
      },
      form: {
        grant_type: 'client_credentials',
        scope: SCOPE
      }
    })

    const response = await request({
      uri,
      method,
      body,
      headers: {
        authorization: `${auth.token_type} ${auth.access_token}`
      }
    })

    console.log(response)
  } catch (error) {
    console.log(`Error: ${error.message}`)
  }
}

sendAPIRequest()

Здесь код будет.envПеременные загружаются в среду, а затем извлекаются из Node. Node хранит переменные среды вprocess.env(processэто глобальная переменная с множеством полезных переменных и функций).

require('dotenv').config()
// ...
const { ISSUER, CLIENT_ID, CLIENT_SECRET, SCOPE } = process.env
// ...

Далее, поскольку это будет запускаться из командной строки, вы снова можете использоватьprocessчтобы получитьprocess.argvпараметры передаются вместе. Это даст вам массив со всеми переданными параметрами. Перед первыми двумя запятыми нет никаких имен переменных, потому что в данном случае первые две не имеют значения; они просто приводят кnodeпуть и имя скрипта (clientилиclient.js).

URL-адрес обязателен, он включает конечную точку, но метод и данные JSON необязательны. Метод по умолчаниюGET, так что вы можете игнорировать его, если вы просто получаете данные. В этом случае вам также не нужна полезная нагрузка. Если аргументы не выглядят правильными, будет использоваться сообщение об ошибке и код выхода.1Выход из программы, которая указывает на ошибку.

const [,, uri, method, body] = process.argv
if (!uri) {
  console.log('Usage: node client {url} [{method}] [{jsonData}]')
  process.exit(1)
}

Node в настоящее время не позволяет использовать в основном потокеawait, поэтому использовать очистительasync/awaitсинтаксис, вы должны создать функцию, а затем вызвать ее.

если в любомawaitЕсли в функции возникает ошибка, она будет напечатана на экранеtry/catch.

const sendAPIRequest = async () => {
  try {
    // ...
  } catch (error) {
    console.error(`Error: ${error.message}`)
  }
}

sendAPIRequest()

Здесь клиент отправляет запрос токена на сервер авторизации. Для авторизации на самом сервере авторизации нужно использовать Basic Auth. Обычная аутентификация — это то же поведение, которое используют браузеры, когда вы получаете встроенное всплывающее окно с запросом имени пользователя и пароля. Предположим, ваше имя пользователяAzureDiamondи ваш парольhunter2. Ваш браузер будет использовать их (:), затем base64 (этоbtoaфункция), чтобы закодировать их, чтобы получитьQXp1cmVEaWFtb25kOmh1bnRlcjI=. Затем он отправляет заголовок авторизацииBasic QXp1cmVEaWFtb25kOmh1bnRlcjI=. Сервер может декодировать токен base64, чтобы получить имя пользователя и пароль.

Сама по себе базовая авторизация небезопасна, потому что ее легко взломать, поэтомуhttpsВажно для атак типа «человек посередине». Здесь Client ID и Client Secret — это имя пользователя и пароль соответственно. Именно поэтому необходимо обеспечитьCLIENT_IDиCLIENT_SECRETпо частным причинам.

Для OAuth 2.0 также необходимо указать тип авторизации, в данном случае этоclient_credentials, потому что вы планируете провести беседу между двумя машинами. Также необходимо указать область действия. Здесь нужно добавить и другие параметры, но это все, что нам нужно для этого примера.

const token = btoa(`${CLIENT_ID}:${CLIENT_SECRET}`)
const auth = await request({
  uri: `${ISSUER}/v1/token`,
  json: true,
  method: 'POST',
  headers: {
    authorization: `Basic ${token}`
  },
  form: {
    grant_type: 'client_credentials',
    scope: SCOPE
  }
})

После того, как вы прошли аутентификацию, вы получите токен доступа, который вы можете отправить в REST API, токен должен выглядеть примерно так:Bearer eyJra...HboUg(Настоящий токен намного длиннее — около 800 символов). Токен содержит всю информацию, необходимую REST API для проверки срока действия токена, а также другую другую информацию, такую ​​как область запроса, эмитент и идентификатор клиента, используемый для токена.

Ответ от REST API выводится на экран.

const response = await request({
  uri,
  method,
  body,
  headers: {
    authorization: `${auth.token_type} ${auth.access_token}`
  }
})

console.log(response)

Попробуй это сейчас. Точно так же сnpm test && node .Запустите приложение и попробуйте некоторые команды, такие как:

$ node client http://localhost:3000/parts | json
[
  {
    "id": 1,
    "partNumber": "abc-123",
    "modelNumber": "xyz-789",
    "name": "Alphabet Soup",
    "description": "Soup with letters and numbers in it",
    "createdAt": "2018-08-16T02:22:09.446Z",
    "updatedAt": "2018-08-16T02:22:09.446Z"
  }
]

$ node client http://localhost:3000/parts post '{
  "partNumber": "ban-bd",
  "modelNumber": 1,
  "name": "Banana Bread",
  "description": "Bread made from bananas"
}' | json
{
  "id": 2,
  "partNumber": "ban-bd",
  "modelNumber": "1",
  "name": "Banana Bread",
  "description": "Bread made from bananas",
  "updatedAt": "2018-08-17T00:23:23.341Z",
  "createdAt": "2018-08-17T00:23:23.341Z"
}

$ node client http://localhost:3000/parts | json
[
  {
    "id": 1,
    "partNumber": "abc-123",
    "modelNumber": "xyz-789",
    "name": "Alphabet Soup",
    "description": "Soup with letters and numbers in it",
    "createdAt": "2018-08-16T02:22:09.446Z",
    "updatedAt": "2018-08-16T02:22:09.446Z"
  },
  {
    "id": 2,
    "partNumber": "ban-bd",
    "modelNumber": "1",
    "name": "Banana Bread",
    "description": "Bread made from bananas",
    "createdAt": "2018-08-17T00:23:23.341Z",
    "updatedAt": "2018-08-17T00:23:23.341Z"
  }
]

$ node client http://localhost:3000/parts/1 delete | json
{}

$ node client http://localhost:3000/parts | json
[
  {
    "id": 2,
    "partNumber": "ban-bd",
    "modelNumber": "1",
    "name": "Banana Bread",
    "description": "Bread made from bananas",
    "createdAt": "2018-08-17T00:23:23.341Z",
    "updatedAt": "2018-08-17T00:23:23.341Z"
  }
]

Узнайте больше об учетных данных клиента Okta Node и OAuth 2.0.

Надеюсь, вы видели, как легко создать REST API в Node и защитить его от неавторизованных пользователей. Теперь, когда у вас появилась возможность создать собственный пример проекта, ознакомьтесь с некоторыми другими замечательными ресурсами по Node, OAuth 2.0 и Okta. Вы также можете просмотреть другие интересные статьи в блоге разработчиков Okta.

Как и раньше, вы можете комментировать ниже или в Twitter@oktadevДайте нам обратную связь или задайте вопросы, мы с нетерпением ждем вашего ответа!

Если вы обнаружите ошибки в переводе или в других областях, требующих доработки, добро пожаловать наПрограмма перевода самородковВы также можете получить соответствующие бонусные баллы за доработку перевода и PR. начало статьиПостоянная ссылка на эту статьюЭто ссылка MarkDown этой статьи на GitHub.


Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из ИнтернетаНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.