Nawiązywanie połączenia z usługą Azure SQL Database i wykonywanie zapytań względem usługi Azure SQL Database przy użyciu pakietu npm Node.js i mssql
Dotyczy: Azure SQL Database
W tym przewodniku Szybki start opisano sposób łączenia aplikacji z bazą danych w usłudze Azure SQL Database i wykonywania zapytań przy użyciu Node.js i mssql. Ten przewodnik Szybki start jest zgodny z zalecanym podejściem bez hasła w celu nawiązania połączenia z bazą danych.
Połączenia bez hasła dla deweloperów
Połączenia bez hasła oferują bezpieczniejszy mechanizm uzyskiwania dostępu do zasobów platformy Azure. Następujące ogólne kroki służą do nawiązywania połączenia z usługą Azure SQL Database przy użyciu połączeń bez hasła w tym artykule:
- Przygotuj środowisko do uwierzytelniania bez hasła.
- W środowisku lokalnym: Używana jest tożsamość osobista. Tę tożsamość można ściągnąć ze środowiska IDE, interfejsu wiersza polecenia lub innych lokalnych narzędzi programistycznych.
- W środowisku chmury: jest używana tożsamość zarządzana.
- Uwierzytelnij się w środowisku przy użyciu biblioteki
DefaultAzureCredential
tożsamości platformy Azure, aby uzyskać zweryfikowane poświadczenia. - Użyj zweryfikowanego poświadczenia, aby utworzyć obiekty klienta zestawu Azure SDK na potrzeby dostępu do zasobów.
Więcej informacji na temat połączeń bez hasła można uzyskać w centrum bez hasła.
Wymagania wstępne
- Subskrypcja platformy Azure
- Baza danych w usłudze Azure SQL Database skonfigurowana do uwierzytelniania przy użyciu identyfikatora Entra firmy Microsoft (dawniej Azure Active Directory). Możesz go utworzyć, korzystając z przewodnika Szybki start Tworzenie bazy danych.
- Powłoka z obsługą powłoki Bash
- Node.js LTS
- Visual Studio Code
- Rozszerzenie usługi App Service programu Visual Studio Code
- Najnowsza wersja interfejsu wiersza polecenia platformy Azure
Konfigurowanie serwera bazy danych
Bezpieczne, bez hasła połączenia z usługą Azure SQL Database wymagają pewnych konfiguracji bazy danych. Sprawdź następujące ustawienia na serwerze logicznym na platformie Azure , aby prawidłowo nawiązać połączenie z usługą Azure SQL Database w środowiskach lokalnych i hostowanych:
W przypadku lokalnych połączeń programistycznych upewnij się, że serwer logiczny jest skonfigurowany tak, aby zezwolić na nawiązywanie połączenia z adresem IP komputera lokalnego i innymi usługami platformy Azure:
Przejdź do strony Sieć serwera.
Przełącz przycisk radiowy Wybrane sieci, aby wyświetlić dodatkowe opcje konfiguracji.
Wybierz pozycję Dodaj adres IPv4 klienta (xx.xx.xx.xx.xx ), aby dodać regułę zapory, która umożliwi połączenia z adresu IPv4 komputera lokalnego. Alternatywnie możesz również wybrać pozycję + Dodaj regułę zapory, aby wprowadzić wybrany konkretny adres IP.
Upewnij się, że pole wyboru Zezwalaj usługom i zasobom platformy Azure na dostęp do tego serwera jest zaznaczone.
Ostrzeżenie
Włączenie opcji Zezwalaj usługom i zasobom platformy Azure na dostęp do tego ustawienia serwera nie jest zalecaną praktyką zabezpieczeń w scenariuszach produkcyjnych. Rzeczywiste aplikacje powinny implementować bezpieczniejsze podejścia, takie jak silniejsze ograniczenia zapory lub konfiguracje sieci wirtualnej.
Więcej informacji na temat konfiguracji zabezpieczeń bazy danych można uzyskać w następujących zasobach:
- Konfigurowanie reguł zapory usługi Azure SQL Database.
- Konfigurowanie sieci wirtualnej z prywatnymi punktami końcowymi.
Serwer musi również mieć włączone uwierzytelnianie Microsoft Entra i mieć przypisane konto administratora firmy Microsoft Entra. W przypadku lokalnych połączeń programistycznych konto administratora firmy Microsoft Entra powinno być kontem, które można również zalogować się do programu Visual Studio lub interfejsu wiersza polecenia platformy Azure lokalnie. Możesz sprawdzić, czy serwer ma włączone uwierzytelnianie firmy Microsoft Entra na stronie Identyfikator entra firmy Microsoft serwera logicznego.
Jeśli używasz osobistego konta platformy Azure, upewnij się, że masz konfigurację usługi Microsoft Entra i skonfigurowaną dla usługi Azure SQL Database w celu przypisania konta jako administratora serwera. Jeśli używasz konta firmowego, identyfikator Firmy Microsoft najprawdopodobniej zostanie już skonfigurowany.
Tworzenie projektu
Kroki opisane w tej sekcji umożliwiają utworzenie interfejsu API REST Node.js.
Utwórz nowy katalog dla projektu i przejdź do niego.
Zainicjuj projekt, uruchamiając następujące polecenie w terminalu:
npm init -y
Zainstaluj wymagane pakiety używane w przykładowym kodzie w tym artykule:
npm install mssql express swagger-ui-express yamljs dotenv
Otwórz projekt w programie Visual Studio Code.
code .
Otwórz plik package.json i dodaj następującą właściwość i wartość po właściwości name, aby skonfigurować projekt dla modułów ESM.
"type": "module",
Tworzenie kodu aplikacji Express.js
Aby utworzyć aplikację Express.js OpenAPI, utworzysz kilka plików:
Plik | opis |
---|---|
.env.development | Lokalny plik środowiska programistycznego. |
index.js | Główny plik aplikacji, który uruchamia aplikację Express.js na porcie 3000. |
person.js | Express.js /person route API plik do obsługi operacji CRUD. |
openapi.js | Express.js /api-docs route for OpenAPI explorer UI (Trasa narzędzia /api-docs dla interfejsu użytkownika eksploratora interfejsu użytkownika interfejsu api interfejsu użytkownika eksploratora interfejsu api). Root przekierowuje do tej trasy. |
openApiSchema.yml | Plik schematu openAPI 3.0 definiujący interfejs API osoby. |
config.js | Plik konfiguracji do odczytywania zmiennych środowiskowych i konstruowania odpowiedniego obiektu połączenia mssql. |
database.js | Klasa bazy danych do obsługi operacji CRUD usługi Azure SQL przy użyciu pakietu npm mssql . |
./vscode/settings.json | Ignoruj pliki według wzorca glob podczas wdrażania. |
Utwórz plik index.js i dodaj następujący kod:
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}`); });
Utwórz plik trasy person.js i dodaj następujący kod:
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;
W przypadku uwierzytelniania bez hasła zmień parametr przekazany na
createDatabaseConnection
wartość zSQLAuthentication
naPasswordlessConfig
.const database = await createDatabaseConnection(PasswordlessConfig);
Utwórz plik trasy openapi.js i dodaj następujący kod dla eksploratora interfejsu użytkownika interfejsu użytkownika interfejsu 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;
Konfigurowanie obiektu połączenia mssql
Pakiet mssql implementuje połączenie z usługą Azure SQL Database, zapewniając ustawienie konfiguracji dla typu uwierzytelniania.
W programie Visual Studio Code utwórz plik config.js i dodaj następujący kod konfiguracji mssql w celu uwierzytelnienia w usłudze 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 } };
Tworzenie lokalnego pliku zmiennej środowiskowej
Tworzenie pliku .env.development dla lokalnych zmiennych środowiskowych
Dodaj następujący tekst i zaktualizuj wartości dla i <YOURSERVERNAME>
<YOURDATABASENAME>
.
AZURE_SQL_SERVER=<YOURSERVERNAME>.database.windows.net
AZURE_SQL_DATABASE=<YOURDATABASENAME>
AZURE_SQL_PORT=1433
AZURE_SQL_AUTHENTICATIONTYPE=azure-active-directory-default
Uwaga
Obiekty konfiguracji bez hasła są bezpieczne do zatwierdzania kontroli źródła, ponieważ nie zawierają żadnych wpisów tajnych, takich jak nazwy użytkowników, hasła lub klucze dostępu.
Dodawanie kodu w celu nawiązania połączenia z usługą Azure SQL Database
Utwórz plik database.js i dodaj następujący kod:
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; };
Lokalne przetestowanie aplikacji
Aplikacja jest gotowa do testowania lokalnie. Upewnij się, że zalogowano się do chmury platformy Azure w programie Visual Studio Code przy użyciu tego samego konta, które zostało ustawione jako administrator bazy danych.
Uruchom aplikację za pomocą następującego polecenia. Aplikacja jest uruchamiana na porcie 3000.
NODE_ENV=development node index.js
Tabela Person jest tworzona w bazie danych podczas uruchamiania tej aplikacji.
W przeglądarce przejdź do eksploratora interfejsu OpenAPI pod adresem http://localhost:3000.
Na stronie Swagger UI rozwiń metodę POST i wybierz pozycję Wypróbuj.
Zmodyfikuj przykładowy kod JSON, aby uwzględnić wartości właściwości. Właściwość ID jest ignorowana.
Wybierz pozycję Wykonaj , aby dodać nowy rekord do bazy danych. Interfejs API zwraca pomyślną odpowiedź.
Rozwiń metodę GET na stronie interfejsu użytkownika programu Swagger i wybierz pozycję Wypróbuj. Wybierz pozycję Wykonaj, a utworzona osoba zostanie zwrócona.
Konfigurowanie projektu na potrzeby wdrażania zip
.vscode
Utwórz folder i utwórz plik settings.json w folderze.Dodaj następujące polecenie, aby zignorować zmienne środowiskowe i zależności podczas wdrażania pliku zip.
{ "appService.zipIgnorePattern": ["./.env*","node_modules{,/**}"] }
Wdrażanie w usłudze Azure App Service
Aplikacja jest gotowa do wdrożenia na platformie Azure. Program Visual Studio Code może utworzyć usługę aplikacja systemu Azure i wdrożyć aplikację w jednym przepływie pracy.
Upewnij się, że aplikacja została zatrzymana.
Zaloguj się do platformy Azure, jeśli jeszcze tego nie zrobiono, wybierając polecenie Azure: Zaloguj się do chmury platformy Azure w palecie poleceń (Ctrl + Shift + P)
W oknie Eksplorator platformy Azure programu Visual Studio Code kliknij prawym przyciskiem myszy węzeł Usługi App Services i wybierz polecenie Utwórz nową aplikację internetową (zaawansowane).
Użyj poniższej tabeli, aby utworzyć usługę App Service:
Monit Wartość Wprowadź globalnie unikatową nazwę nowej aplikacji internetowej. Wprowadź monit, taki jak azure-sql-passwordless
. Post-pend unikatowy ciąg, taki jak123
.Wybierz grupę zasobów dla nowych zasobów. Wybierz pozycję +Utwórz nową grupę zasobów, a następnie wybierz nazwę domyślną. Wybierz stos środowiska uruchomieniowego. Wybierz wersję LTS stosu Node.js. Wybierz system operacyjny. Wybierz pozycję Linux. Wybierz lokalizację nowych zasobów. Wybierz blisko siebie lokalizację. Wybierz plan usługi App Service dla systemu Linux. Wybierz pozycję Utwórz nowy plan usługi App Service. Następnie wybierz nazwę domyślną. Wybierz warstwę cenową. Wybierz pozycję Bezpłatna (F1). Wybierz zasób usługi Application Insights dla aplikacji. Wybierz pozycję Pomiń na razie. Przed kontynuowaniem poczekaj na powiadomienie, że aplikacja została utworzona.
W eksploratorze platformy Azure rozwiń węzeł App Services i kliknij prawym przyciskiem myszy nową aplikację.
Wybierz pozycję Wdróż w aplikacji internetowej.
Wybierz folder główny projektu JavaScript.
Po wyświetleniu wyskakującego okna podręcznego programu Visual Studio Code wybierz pozycję Wdróż.
Po zakończeniu wdrażania aplikacja nie działa poprawnie na platformie Azure. Nadal musisz skonfigurować bezpieczne połączenie między usługą App Service i bazą danych SQL, aby pobrać dane.
Łączenie usługi App Service z usługą Azure SQL Database
Aby połączyć wystąpienie usługi App Service z usługą Azure SQL Database, wymagane są następujące kroki:
- Utwórz tożsamość zarządzaną dla usługi App Service.
- Utwórz użytkownika bazy danych SQL i skojarz ją z tożsamością zarządzaną usługi App Service.
- Przypisz role SQL do użytkownika bazy danych, który zezwala na odczyt, zapis i potencjalnie inne uprawnienia.
Dostępnych jest wiele narzędzi do implementowania następujących kroków:
Łącznik usług to narzędzie, które usprawnia uwierzytelnianie połączeń między różnymi usługami na platformie Azure. Łącznik usługi obsługuje obecnie łączenie usługi App Service z bazą danych Azure SQL Database za pośrednictwem interfejsu wiersza polecenia platformy az webapp connection create sql
Azure przy użyciu polecenia . To pojedyncze polecenie wykonuje trzy kroki wymienione powyżej.
Tworzenie tożsamości zarządzanej za pomocą łącznika usługi
Uruchom następujące polecenie w usłudze Cloud Shell w witrynie Azure Portal. Usługa Cloud Shell ma najnowszą wersję interfejsu wiersza polecenia platformy Azure. Zastąp zmienne własnymi <>
wartościami.
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
Weryfikowanie ustawień aplikacji usługi App Service
Zmiany wprowadzone przez łącznik usługi można sprawdzić w ustawieniach usługi App Service.
W programie Visual Studio Code w eksploratorze platformy Azure kliknij prawym przyciskiem myszy usługę App Service i wybierz polecenie Otwórz w portalu.
Przejdź do strony Tożsamość dla usługi App Service. Na karcie Przypisane przez system stan powinien być ustawiony na Włączone. Ta wartość oznacza, że tożsamość zarządzana przypisana przez system została włączona dla aplikacji.
Przejdź do strony Konfiguracja usługi App Service. Na karcie Ustawienia aplikacji powinien zostać wyświetlonych kilka zmiennych środowiskowych, które znajdowały się już w obiekcie konfiguracji mssql.
AZURE_SQL_SERVER
AZURE_SQL_DATABASE
AZURE_SQL_PORT
AZURE_SQL_AUTHENTICATIONTYPE
Nie usuwaj ani nie zmieniaj nazw właściwości ani wartości.
Testowanie wdrożonej aplikacji
Przejdź do adresu URL aplikacji, aby sprawdzić, czy połączenie z usługą Azure SQL Database działa. Adres URL aplikacji można znaleźć na stronie przeglądu usługi App Service.
Osoba utworzona lokalnie powinna być wyświetlana w przeglądarce. Gratulacje! Aplikacja jest teraz połączona z usługą Azure SQL Database zarówno w środowiskach lokalnych, jak i hostowanych.
Napiwek
Jeśli podczas testowania wystąpi błąd 500 Wewnętrzny serwer, może to być spowodowane konfiguracjami sieci bazy danych. Sprawdź, czy serwer logiczny jest skonfigurowany z ustawieniami opisanymi w sekcji Konfigurowanie bazy danych .
Oczyszczanie zasobów
Po zakończeniu pracy z usługą Azure SQL Database usuń zasób, aby uniknąć niezamierzonych kosztów.
Na pasku wyszukiwania w witrynie Azure Portal wyszukaj ciąg Azure SQL i wybierz pasujący wynik.
Znajdź i wybierz bazę danych na liście baz danych.
Na stronie Przegląd usługi Azure SQL Database wybierz pozycję Usuń.
Na platformie Azure na pewno chcesz usunąć otwieraną stronę, wpisz nazwę bazy danych, aby potwierdzić, a następnie wybierz pozycję Usuń.
Przykładowy kod
Dostępny jest przykładowy kod dla tej aplikacji: