Připojení ke službě Azure SQL Database a jejich dotazování pomocí balíčku Node.js a mssql npm
Platí pro:Azure SQL Database
Tento rychlý start popisuje, jak připojit aplikaci k databázi ve službě Azure SQL Database a provádět dotazy pomocí Node.js a mssql. Tento rychlý start se řídí doporučeným přístupem bez hesla pro připojení k databázi.
Připojení bez hesel pro vývojáře
Připojení bez hesla nabízejí bezpečnější mechanismus pro přístup k prostředkům Azure. Následující základní kroky slouží k připojení ke službě Azure SQL Database pomocí připojení bez hesla v tomto článku:
- Připravte prostředí na ověřování bez hesla.
- Pro místní prostředí: Používá se vaše osobní identita. Tuto identitu je možné načíst z integrovaného vývojového prostředí, rozhraní příkazového řádku nebo jiných místních vývojových nástrojů.
- V cloudovém prostředí se používá spravovaná identita .
- Ověřte se v prostředí pomocí
DefaultAzureCredential
knihovny identit Azure a získejte ověřené přihlašovací údaje. - Pomocí ověřených přihlašovacích údajů vytvořte objekty klienta Azure SDK pro přístup k prostředkům.
Další informace o připojeních bez hesel najdete v centru bez hesel.
Požadavky
- Předplatné Azure
- Databáze ve službě Azure SQL Database nakonfigurovaná pro ověřování pomocí Microsoft Entra ID (dříve Azure Active Directory). Můžete ji vytvořit pomocí průvodce rychlým spuštěním pro vytvoření databáze.
- Shell s podporou bash
- Node.js LTS
- Visual Studio Code
- Rozšíření Visual Studio Code App Service
- Nejnovější verze Azure CLI
Konfigurace databázového serveru
Zabezpečená bez hesla připojení ke službě Azure SQL Database vyžadují určité konfigurace databáze. Ověřte na logickém serveru v Azure následující nastavení, abyste se mohli správně připojit ke službě Azure SQL Database v místním i hostovaným prostředí:
V případě místních vývojových připojení se ujistěte, že je váš logický server nakonfigurovaný tak, aby umožňoval připojení IP adresy místního počítače a dalších služeb Azure:
Přejděte na stránku Sítě vašeho serveru.
Přepněte přepínač Vybrané sítě, aby se zobrazily další možnosti konfigurace.
Vyberte Přidat adresu IPv4 klienta (xx.xx.xx.xx) a přidejte pravidlo brány firewall, které povolí připojení z adresy IPv4 místního počítače. Případně můžete také vybrat + Přidat pravidlo brány firewall a podle svého výběru zadat konkrétní IP adresu.
Ujistěte se, že je zaškrtnuté políčko Povolit službám a prostředkům Azure přístup k tomuto serveru .
Varování
Povolení přístupu ke službám a prostředkům Azure pro přístup k tomuto nastavení serveru není doporučeným postupem zabezpečení pro produkční scénáře. Skutečné aplikace by měly implementovat bezpečnější přístupy, jako jsou silnější omezení brány firewall nebo konfigurace virtuální sítě.
Další informace o konfiguracích zabezpečení databáze najdete v následujících zdrojích informací:
- Konfigurujte pravidla brány firewall služby Azure SQL Database
- Nakonfigurujte virtuální síť s privátními koncovými body.
Server musí mít také povolené ověřování Microsoft Entra a musí mít přiřazený účet správce Microsoft Entra. Pro místní vývojová připojení by měl být účet správce Microsoft Entra účtem, ke kterým se můžete také přihlásit do sady Visual Studio nebo Azure CLI místně. Můžete ověřit, zda má váš server povolené ověřování Microsoft Entra na stránce Microsoft Entra ID vašeho logického serveru.
Pokud používáte osobní účet Azure, ujistěte se, že máte nastaveny a nakonfigurovány Microsoft Entra ID pro Azure SQL Database, abyste mohli přiřadit svůj účet jako správce serveru. Pokud používáte podnikový účet, bude pravděpodobně již nakonfigurován pro vás Microsoft Entra ID.
Vytvoření projektu
Kroky v této části vytvoří Node.js rozhraní REST API.
Vytvořte pro projekt nový adresář a přejděte do něj.
Inicializace projektu spuštěním následujícího příkazu v terminálu:
npm init -y
Nainstalujte požadované balíčky použité v ukázkovém kódu v tomto článku:
npm install mssql express swagger-ui-express yamljs dotenv
Otevřete projekt v editoru Visual Studio Code.
code .
Otevřete soubor
package.json
a po vlastnosti s názvem přidejte následující vlastnost a hodnotu pro konfiguraci projektu pro moduly ESM."type": "module",
Vytvoření kódu aplikace Express.js
Pokud chcete vytvořit aplikaci Express.js OpenAPI, vytvoříte několik souborů:
Soubor | Popis |
---|---|
.env.development |
Místní soubor prostředí jen pro vývoj |
index.js |
Hlavní soubor aplikace, který spouští aplikaci Express.js na portu 3000. |
person.js |
Express.js /person směruje soubor rozhraní API pro zpracování operací CRUD. |
openapi.js |
Trasování Express.js /api-docs pro uživatelské rozhraní OpenAPI Explorer. Kořen přesměruje na tuto trasu. |
openApiSchema.yml |
Soubor schématu OpenAPI 3.0 definující rozhraní API pro osoby |
config.js |
Konfigurační soubor pro čtení proměnných prostředí a vytvoření příslušného objektu připojení mssql. |
database.js |
Třída pro práci s databázemi za účelem provádění CRUD operací v Azure SQL pomocí npm balíčku mssql. |
./vscode/settings.json |
Během nasazování ignorujte soubory podle vzoru globu. |
Vytvořte soubor
index.js
a přidejte následující kód:import express from 'express'; // Import App routes import person from './person.js'; import openapi from './openapi.js'; const port = process.env.PORT || 3000; const app = express(); // Connect App routes app.use('/api-docs', openapi); app.use('/persons', person); app.use('*', (_, res) => { res.redirect('/api-docs'); }); // Start the server app.listen(port, () => { console.log(`Server started on port ${port}`); });
Vytvořte
person.js
směrovací soubor a přidejte následující kód:import express from 'express'; import { passwordConfig as SQLAuthentication, noPasswordConfig as PasswordlessConfig } from './config.js'; import { createDatabaseConnection } from './database.js'; const router = express.Router(); router.use(express.json()); const database = await createDatabaseConnection(SQLAuthentication); router.get('/', async (req, res) => { try { // Return a list of persons const persons = await database.readAll(); console.log(`persons: ${JSON.stringify(persons)}`); res.status(200).json(persons); } catch (err) { res.status(500).json({ error: err?.message }); } }); router.post('/', async (req, res) => { try { // add a person const person = req.body; console.log(`person: ${JSON.stringify(person)}`); const rowsAffected = await database.create(person); res.status(201).json({ rowsAffected }); } catch (err) { res.status(500).json({ error: err?.message }); } }); router.get('/:id', async (req, res) => { try { // Get the person with the specified ID const personId = req.params.id; console.log(`personId: ${personId}`); if (personId) { const result = await database.read(personId); console.log(`persons: ${JSON.stringify(result)}`); res.status(200).json(result); } else { res.status(404); } } catch (err) { res.status(500).json({ error: err?.message }); } }); router.put('/:id', async (req, res) => { try { // Update the person with the specified ID const personId = req.params.id; console.log(`personId: ${personId}`); const person = req.body; if (personId && person) { delete person.id; console.log(`person: ${JSON.stringify(person)}`); const rowsAffected = await database.update(personId, person); res.status(200).json({ rowsAffected }); } else { res.status(404); } } catch (err) { res.status(500).json({ error: err?.message }); } }); router.delete('/:id', async (req, res) => { try { // Delete the person with the specified ID const personId = req.params.id; console.log(`personId: ${personId}`); if (!personId) { res.status(404); } else { const rowsAffected = await database.delete(personId); res.status(204).json({ rowsAffected }); } } catch (err) { res.status(500).json({ error: err?.message }); } }); export default router;
Pro ověřování bez hesla změňte parametr předaný z
createDatabaseConnection
SQLAuthentication
naPasswordlessConfig
.const database = await createDatabaseConnection(PasswordlessConfig);
Vytvořte soubor trasy
openapi.js
a přidejte následující kód pro Průzkumníka uživatelského rozhraní OpenAPI:import express from 'express'; import { join, dirname } from 'path'; import swaggerUi from 'swagger-ui-express'; import yaml from 'yamljs'; import { fileURLToPath } from 'url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const router = express.Router(); router.use(express.json()); const pathToSpec = join(__dirname, './openApiSchema.yml'); const openApiSpec = yaml.load(pathToSpec); router.use('/', swaggerUi.serve, swaggerUi.setup(openApiSpec)); export default router;
Vytvořte soubor
openApiSchema.yml
a přidejte následující kód, aby Průzkumník uživatelského rozhraní OpenAPI věděl, jaká rozhraní API a modely se mají zobrazit:openapi: 3.0.0 info: version: 1.0.0 title: Persons API paths: /persons: get: summary: Get all persons responses: '200': description: OK content: application/json: schema: type: array items: $ref: '#/components/schemas/Person' post: summary: Create a new person requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Person' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/Person' /persons/{id}: parameters: - name: id in: path required: true schema: type: integer get: summary: Get a person by ID responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Person' '404': description: Person not found put: summary: Update a person by ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Person' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Person' '404': description: Person not found delete: summary: Delete a person by ID responses: '204': description: No Content '404': description: Person not found components: schemas: Person: type: object properties: id: type: integer readOnly: true firstName: type: string lastName: type: string
Konfigurace objektu připojení mssql
Balíček mssql implementuje připojení ke službě Azure SQL Database poskytnutím konfiguračního nastavení pro typ ověřování.
V editoru Visual Studio Code vytvořte soubor
config.js
a přidejte následující konfigurační kód mssql pro ověření ve službě Azure SQL Database.import * as dotenv from 'dotenv'; if(process.env.NODE_ENV === 'development') { dotenv.config({ path: `.env.${process.env.NODE_ENV}`, debug: true }); } // TIP: Port must be a number, not a string! const server = process.env.AZURE_SQL_SERVER; const database = process.env.AZURE_SQL_DATABASE; const port = +process.env.AZURE_SQL_PORT; const type = process.env.AZURE_SQL_AUTHENTICATIONTYPE; const user = process.env.AZURE_SQL_USER; const password = process.env.AZURE_SQL_PASSWORD; export const noPasswordConfig = { server, port, database, authentication: { type }, options: { encrypt: true } }; export const passwordConfig = { server, port, database, user, password, options: { encrypt: true } };
Vytvořte soubor pro lokální proměnné prostředí
Vytvoření souboru .env.development
pro místní proměnné prostředí
Přidejte následující text a aktualizujte hodnoty pro <YOURSERVERNAME>
a <YOURDATABASENAME>
.
AZURE_SQL_SERVER=<YOURSERVERNAME>.database.windows.net
AZURE_SQL_DATABASE=<YOURDATABASENAME>
AZURE_SQL_PORT=1433
AZURE_SQL_AUTHENTICATIONTYPE=azure-active-directory-default
Poznámka:
Objekty konfigurace bez hesla jsou bezpečné pro potvrzení do správy zdrojového kódu, protože neobsahují žádné tajné kódy, jako jsou uživatelská jména, hesla nebo přístupové klíče.
Přidání kódu pro připojení ke službě Azure SQL Database
Vytvořte soubor
database.js
a přidejte následující kód:import sql from 'mssql'; let database = null; export default class Database { config = {}; poolconnection = null; connected = false; constructor(config) { this.config = config; } async connect() { try { this.poolconnection = await sql.connect(this.config); this.connected = true; console.log('Database connected successfully.'); return this.poolconnection; } catch (error) { console.error('Error connecting to the database:', error); this.connected = false; } } async disconnect() { try { if (this.connected) { await this.poolconnection.close(); this.connected = false; console.log('Database disconnected successfully.'); } } catch (error) { console.error('Error disconnecting from the database:', error); } } async executeQuery(query) { const request = this.poolconnection.request(); const result = await request.query(query); return result.rowsAffected[0]; } async create(data) { const request = this.poolconnection.request(); request.input('firstName', sql.NVarChar(255), data.firstName); request.input('lastName', sql.NVarChar(255), data.lastName); const result = await request.query( `INSERT INTO Person (firstName, lastName) VALUES (@firstName, @lastName)` ); return result.rowsAffected[0]; } async readAll() { const request = this.poolconnection.request(); const result = await request.query(`SELECT * FROM Person`); return result.recordsets[0]; } async read(id) { const request = this.poolconnection.request(); const result = await request .input('id', sql.Int, +id) .query(`SELECT * FROM Person WHERE id = @id`); return result.recordset[0]; } async update(id, data) { const request = this.poolconnection.request(); request.input('id', sql.Int, +id); request.input('firstName', sql.NVarChar(255), data.firstName); request.input('lastName', sql.NVarChar(255), data.lastName); const result = await request.query( `UPDATE Person SET firstName=@firstName, lastName=@lastName WHERE id = @id` ); return result.rowsAffected[0]; } async delete(id) { const idAsNumber = Number(id); const request = this.poolconnection.request(); const result = await request .input('id', sql.Int, idAsNumber) .query(`DELETE FROM Person WHERE id = @id`); return result.rowsAffected[0]; } async createTable() { if (process.env.NODE_ENV === 'development') { this.executeQuery( `IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Person') BEGIN CREATE TABLE Person ( id int NOT NULL IDENTITY, firstName varchar(255), lastName varchar(255) ); END` ) .then(() => { console.log('Table created'); }) .catch((err) => { // Table may already exist console.error(`Error creating table: ${err}`); }); } } } export const createDatabaseConnection = async (passwordConfig) => { database = new Database(passwordConfig); await database.connect(); await database.createTable(); return database; };
Místní testování aplikace
Aplikace je připravená k místnímu otestování. Ujistěte se, že jste přihlášení ke cloudu Azure v editoru Visual Studio Code pomocí stejného účtu, který jste nastavili jako správce vaší databáze.
Spusťte aplikaci pomocí následujícího příkazu. Aplikace se spustí na portu 3000.
NODE_ENV=development node index.js
Tabulka Person se vytvoří v databázi při spuštění této aplikace.
V prohlížeči přejděte do Průzkumníka OpenAPI na adrese http://localhost:3000.
Na stránce s uživatelským rozhraním Swagger rozbalte metodu POST a vyberte Vyzkoušet.
Upravte ukázkový JSON tak, aby zahrnoval hodnoty pro vlastnosti. Vlastnost ID je ignorována.
Vyberte Spustit a přidejte do databáze nový záznam. Rozhraní API vrátí úspěšnou odpověď.
Rozbalte metodu GET na stránce uživatelského rozhraní Swagger a vyberte Vyzkoušet. Vyberte Spustit a vrátí se osoba, kterou jste právě vytvořili.
Konfigurace projektu pro nasazení archivu ZIP
Vytvořte složku
.vscode
a ve složce vytvořte souborsettings.json
.Přidáním následujícího příkazu můžete ignorovat proměnné prostředí a závislosti během nasazování souboru ZIP.
{ "appService.zipIgnorePattern": ["./.env*","node_modules{,/**}"] }
Nasazení do Azure App Service
Aplikace je připravená k nasazení do Azure. Visual Studio Code může vytvořit službu Aplikace Azure a nasadit aplikaci v jednom pracovním postupu.
Ujistěte se, že je aplikace zastavená.
Pokud jste to ještě neudělali, přihlaste se k Azure tak, že v paletě příkazů vyberete příkaz Azure: Přihlásit se ke cloudu (Ctrl + + P).
V okně Azure Explorer editoru Visual Studio Code klikněte pravým tlačítkem na uzel App Services a vyberte Create New Web App (Advanced).
K vytvoření služby App Service použijte následující tabulku:
Podnět Hodnota Zadejte globálně jedinečný název nové webové aplikace. Zadejte výzvu, například azure-sql-passwordless
. Přidejte na konec jedinečný řetězec, například123
.Vyberte skupinu prostředků pro nové zdroje. Vyberte +Vytvořit novou skupinu prostředků a pak vyberte výchozí název. Vyberte běhové prostředí. Vyberte verzi LTS balíčku Node.js. Vyberte operační systém. Vyberte Linux. Vyberte umístění pro nové prostředky. Vyberte umístění blízko vás. Vyberte plán služby App Service pro Linux. Vyberte Vytvořit nový plán služby App Service. Pak vyberte výchozí název. Vyberte cenovou úroveň. Vyberte free (F1). Vyberte prostředek Application Insights pro vaši aplikaci. Vyberte Přeskočit prozatím. Počkejte na oznámení o vytvoření vaší aplikace, než budete pokračovat.
V Azure Exploreru rozbalte uzel Služby App Services a klikněte pravým tlačítkem na novou aplikaci.
Vyberte Nasadit do webové aplikace.
Vyberte kořenovou složku projektu JavaScriptu.
Jakmile se zobrazí automaticky otevírané okno editoru Visual Studio Code, vyberte Nasadit.
Po dokončení nasazení aplikace v Azure nefunguje správně. Stále potřebujete nakonfigurovat zabezpečené připojení mezi službou App Service a databází SQL pro načtení dat.
Připojení služby App Service ke službě Azure SQL Database
Pro připojení instance služby App Service ke službě Azure SQL Database jsou potřeba následující kroky:
- Vytvořte spravovanou identitu pro službu App Service.
- Vytvořte uživatele databáze SQL a přidružte ho ke spravované identitě služby App Service.
- Přiřaďte databázovému uživateli role SQL, které umožňují čtení, zápis a potenciálně další oprávnění.
K dispozici je několik nástrojů pro implementaci těchto kroků:
Service Connector je nástroj, který zjednodušuje ověřená připojení mezi různými službami v Azure. Konektor služby v současné době podporuje připojení služby App Service k databázi Azure SQL přes Azure CLI pomocí az webapp connection create sql
příkazu. Tento jediný příkaz dokončí tři kroky uvedené výše.
Vytvořte spravovanou identitu pomocí konektoru služby
V Cloud Shellu na webu Azure Portal spusťte následující příkaz. Cloud Shell má nejnovější verzi Azure CLI. Nahraďte proměnné <>
vlastními hodnotami.
az webapp connection create sql \
-g <app-service-resource-group> \
-n <app-service-name> \
--tg <database-server-resource-group> \
--server <database-server-name> \
--database <database-name> \
--system-identity
Ověření nastavení aplikace služby App Service
Změny provedené konektorem služby můžete ověřit v nastavení služby App Service.
V editoru Visual Studio Code v Průzkumníku Azure klikněte pravým tlačítkem na váš App Service a vyberte Otevřít v portálu.
Přejděte na stránku Identita vaší služby App Service.
Pod kartou Systém přiřazený by měl býtstav nastaven naZapnuto . Tato hodnota znamená, že pro vaši aplikaci byla povolena spravovaná identita přiřazená systémem.Přejděte na stránku Konfigurace vaší služby App Service. Na kartě Nastavení aplikace byste měli vidět několik proměnných prostředí, které už byly v objektu konfigurace mssql.
AZURE_SQL_SERVER
AZURE_SQL_DATABASE
AZURE_SQL_PORT
AZURE_SQL_AUTHENTICATIONTYPE
Neodstraňovat ani měnit názvy nebo hodnoty vlastností.
Otestování nasazené aplikace
Přejděte na adresu URL aplikace a otestujte, že funguje připojení ke službě Azure SQL Database. Adresu URL aplikace najdete na stránce přehledu služby App Service.
Osoba, kterou jste vytvořili místně, by se měla zobrazit v prohlížeči. Gratulujeme! Vaše aplikace je teď připojená ke službě Azure SQL Database v místním i hostovaným prostředí.
Doporučení
Pokud při testování dojde k vnitřní chybě serveru 500, může to být způsobeno konfigurací sítě databáze. Ověřte, že je váš logický server nakonfigurovaný s nastavením popsanými v části Konfigurace databáze .
Ukliďte zdroje
Po dokončení práce se službou Azure SQL Database odstraňte prostředek, abyste se vyhnuli nezamýšleným nákladům.
Na panelu hledání na webu Azure Portal vyhledejte Azure SQL a vyberte odpovídající výsledek.
Vyhledejte a vyberte databázi v seznamu databází.
Na stránce Přehled služby Azure SQL Database vyberte Odstranit.
Na stránce Azure, kterou opravdu chcete odstranit, která se otevře, zadejte název databáze, abyste ji potvrdili, a pak vyberte Odstranit.
Ukázkový kód
Ukázkový kód pro tuto aplikaci je k dispozici: