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í rychlého startu Pro vytvoření databáze.
- Prostředí s podporou bashe
- 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 zadat konkrétní IP adresu podle vašeho výběru.
Ujistěte se, že je zaškrtnuté políčko Povolit službám a prostředkům Azure přístup k tomuto serveru .
Upozorňující
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í:
- Konfigurace pravidel 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 nastavené a nakonfigurované Microsoft Entra pro Azure SQL Database , abyste mohli účet přiřadit jako správce serveru. Pokud používáte podnikový účet, Bude pro vás pravděpodobně již nakonfigurované ID Microsoft Entra.
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 za vlastnost názvu přidejte následující vlastnost a hodnotu a nakonfigurujte projekt 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 | Express.js trasu /api-docs pro uživatelské rozhraní Průzkumníka OpenAPI. 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 | Database class to handle Azure SQL CRUD operations using the mssql npm package. |
./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;
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ření souboru místní 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í zip
Vytvořte
.vscode
složku a vytvořte v této složce soubor settings.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 + Shift + P).
V okně Azure Explorer v editoru Visual Studio Code klikněte pravým tlačítkem na uzel App Services a vyberte Vytvořit novou webovou aplikaci (Upřesnit).
K vytvoření služby App Service použijte následující tabulku:
Instrukce Hodnota Zadejte globálně jedinečný název nové webové aplikace. Zadejte výzvu, například azure-sql-passwordless
. Post-pend jedinečný řetězec, například123
.Vyberte skupinu prostředků pro nové prostředky. Vyberte +Vytvořit novou skupinu prostředků a pak vyberte výchozí název. Vyberte zásobník modulu runtime. Vyberte verzi LTS zásobní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. Prozatím vyberte Přeskočit. Než budete pokračovat, počkejte na vytvoření aplikace.
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ření spravované identity 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 službu App Service a vyberte Otevřít na portálu.
Přejděte na stránku Identita vaší služby App Service. Pod kartou Přiřazený systém by měl být stav nastaven na Zapnuto. 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í.
Tip
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 .
Vyčištění prostředků
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: