Dela via


Anslut till och fråga Azure SQL Database med hjälp av Node.js och mssql npm-paket

Gäller för:Azure SQL Database

Den här snabbstarten beskriver hur du ansluter ett program till en databas i Azure SQL Database och utför frågor med hjälp av Node.js och mssql. Den här snabbstarten följer den rekommenderade metoden för lösenordsfri anslutning till databasen.

Lösenordslösa anslutningar för utvecklare

Lösenordslösa anslutningar erbjuder en säkrare mekanism för åtkomst till Azure-resurser. Följande övergripande steg används för att ansluta till Azure SQL Database med lösenordslösa anslutningar i den här artikeln:

  • Förbered din miljö för lösenordsfri autentisering.
    • För en lokal miljö: Din personliga identitet används. Den här identiteten kan hämtas från en IDE, CLI eller andra lokala utvecklingsverktyg.
    • För en molnmiljö: En hanterad identitet används.
  • Autentisera i miljön med hjälp av DefaultAzureCredential från Azure Identity-biblioteket för att hämta en verifierad autentiseringsuppgift.
  • Använd verifierade autentiseringsuppgifter för att skapa Azure SDK-klientobjekt för resursåtkomst.

Du kan lära dig mer om lösenordslösa anslutningar på den lösenordslösa hubben.

Förutsättningar

Konfigurera databasservern

Säkra, lösenordslösa anslutningar till Azure SQL Database kräver vissa databaskonfigurationer. Kontrollera följande inställningar på den logiska servern i Azure för att ansluta till Azure SQL Database korrekt i både lokala och värdbaserade miljöer:

  1. För lokala utvecklingsanslutningar kontrollerar du att den logiska servern är konfigurerad så att din lokala dators IP-adress och andra Azure-tjänster kan ansluta:

    • Gå till sidan Nätverk på servern.

    • Växla alternativknappen Valda nätverk för att visa ytterligare konfigurationsalternativ.

    • Välj Lägg till din klient-IPv4-adress(xx.xx.xx.xx) för att lägga till en brandväggsregel som aktiverar anslutningar från den lokala datorns IPv4-adress. Du kan också välja + Lägg till en brandväggsregel för att ange en specifik IP-adress.

    • Kontrollera att kryssrutan Tillåt Azure-tjänster och resurser att komma åt den här servern är markerad.

      A screenshot showing how to configure firewall rules.

      Varning

      Att aktivera inställningen Tillåt Azure-tjänster och resurser att komma åt den här serverinställningen är inte en rekommenderad säkerhetspraxis för produktionsscenarier. Verkliga program bör implementera säkrare metoder, till exempel starkare brandväggsbegränsningar eller konfigurationer av virtuella nätverk.

      Du kan läsa mer om databassäkerhetskonfigurationer på följande resurser:

  2. Servern måste också ha Microsoft Entra-autentisering aktiverat och ha ett Microsoft Entra-administratörskonto tilldelat. För lokala utvecklingsanslutningar ska Microsoft Entra-administratörskontot vara ett konto som du också kan logga in på Visual Studio eller Azure CLI med lokalt. Du kan kontrollera om din server har Microsoft Entra-autentisering aktiverat på sidan Microsoft Entra-ID för den logiska servern.

    A screenshot showing how to enable Microsoft Entra authentication.

  3. Om du använder ett personligt Azure-konto kontrollerar du att microsoft Entra har konfigurerats och konfigurerats för Azure SQL Database för att tilldela ditt konto som serveradministratör. Om du använder ett företagskonto är Microsoft Entra-ID förmodligen redan konfigurerat åt dig.

Skapa projektet

Stegen i det här avsnittet skapar ett Node.js REST API.

  1. Skapa en ny katalog för projektet och navigera till den.

  2. Initiera projektet genom att köra följande kommando i terminalen:

    npm init -y
    
  3. Installera de nödvändiga paketen som används i exempelkoden i den här artikeln:

    npm install mssql swagger-ui-express yamljs
    
  4. Installera utvecklingspaketet som används i exempelkoden i den här artikeln:

    npm install --save-dev dotenv 
    
  5. Öppna projektet i Visual Studio Code.

    code .
    
  6. Öppna filen package.json och lägg till följande egenskap och värde efter namnegenskapenför att konfigurera projektet för ESM-moduler.

    "type": "module",
    

Skapa Express.js programkod

Om du vill skapa Express.js OpenAPI-programmet skapar du flera filer:

Fil beskrivning
.env.development Miljöfil endast för lokal utveckling.
index.js Huvudprogramfilen, som startar Express.js-appen på port 3000.
person.js Express.js/person dirigerar API-filen för att hantera CRUD-åtgärder.
openapi.js Express.js /api-docs-väg för OpenAPI Explorer-användargränssnittet. Rotomdirigeringar till den här vägen.
openApiSchema.yml OpenAPI 3.0-schemafil som definierar person-API.
config.js Konfigurationsfil för att läsa miljövariabler och konstruera lämpligt mssql-anslutningsobjekt.
database.js Databasklass för att hantera Azure SQL CRUD-åtgärder med hjälp av mssql npm-paketet.
./vscode/settings.json Ignorera filer efter globmönster under distributionen.
  1. Skapa en index.js fil och lägg till följande kod:

    import express from 'express';
    import { config } from './config.js';
    import Database from './database.js';
    
    // Import App routes
    import person from './person.js';
    import openapi from './openapi.js';
    
    const port = process.env.PORT || 3000;
    
    const app = express();
    
    // Development only - don't do in production
    // Run this to create the table in the database
    if (process.env.NODE_ENV === 'development') {
      const database = new Database(config);
      database
        .executeQuery(
          `CREATE TABLE Person (id int NOT NULL IDENTITY, firstName varchar(255), lastName varchar(255));`
        )
        .then(() => {
          console.log('Table created');
        })
        .catch((err) => {
          // Table may already exist
          console.error(`Error creating table: ${err}`);
        });
    }
    
    // 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}`);
    });
    
  2. Skapa en person.js vägfil och lägg till följande kod:

    import express from 'express';
    import { config } from './config.js';
    import Database from './database.js';
    
    const router = express.Router();
    router.use(express.json());
    
    // Development only - don't do in production
    console.log(config);
    
    // Create database object
    const database = new Database(config);
    
    router.get('/', async (_, 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 {
        // Create 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;
    
    
  3. Skapa en opanapi.js vägfil och lägg till följande kod för OpenAPI UI Explorer:

    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;
    
  4. Skapa en openApiSchema.yml schemafil och lägg till följande YAML:

    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
    

Konfigurera mssql-anslutningsobjektet

Mssql-paketet implementerar anslutningen till Azure SQL Database genom att tillhandahålla en konfigurationsinställning för en autentiseringstyp.

  1. I Visual Studio Code skapar du en config.js-fil och lägger till följande mssql-konfigurationskod för att autentisera till Azure SQL Database.

    import * as dotenv from 'dotenv';
    dotenv.config({ path: `.env.${process.env.NODE_ENV}`, debug: true });
    
    const server = process.env.AZURE_SQL_SERVER;
    const database = process.env.AZURE_SQL_DATABASE;
    const port = parseInt(process.env.AZURE_SQL_PORT);
    const type = process.env.AZURE_SQL_AUTHENTICATIONTYPE;
    
    export const config = {
        server,
        port,
        database,
        authentication: {
            type
        },
        options: {
            encrypt: true
        }
    };
    
  2. Skapa en .env.development-fil för dina lokala miljövariabler och lägg till följande text och uppdatering med dina värden för <YOURSERVERNAME> och <YOURDATABASENAME>.

    AZURE_SQL_SERVER=<YOURSERVERNAME>.database.windows.net
    AZURE_SQL_DATABASE=<YOURDATABASENAME>
    AZURE_SQL_PORT=1433
    AZURE_SQL_AUTHENTICATIONTYPE=azure-active-directory-default
    

Kommentar

Lösenordslösa konfigurationsobjekt är säkra att checka in på källkontrollen, eftersom de inte innehåller några hemligheter som användarnamn, lösenord eller åtkomstnycklar.

  1. Skapa en .vscode mapp och skapa en settings.json fil i mappen.

  2. Lägg till följande för att ignorera miljövariabler och beroenden under zip-distributionen.

    {
        "appService.zipIgnorePattern": ["./.env*","node_modules{,/**}"]
    }
    

Lägg till koden för att ansluta till Azure SQL Database

  1. Skapa en database.js fil och lägg till följande kod:

    import sql from 'mssql';
    
    export default class Database {
      config = {};
      poolconnection = null;
      connected = false;
    
      constructor(config) {
        this.config = config;
        console.log(`Database: config: ${JSON.stringify(config)}`);
      }
    
      async connect() {
        try {
          console.log(`Database connecting...${this.connected}`);
          if (this.connected === false) {
            this.poolconnection = await sql.connect(this.config);
            this.connected = true;
            console.log('Database connection successful');
          } else {
            console.log('Database already connected');
          }
        } catch (error) {
          console.error(`Error connecting to database: ${JSON.stringify(error)}`);
        }
      }
    
      async disconnect() {
        try {
          this.poolconnection.close();
          console.log('Database connection closed');
        } catch (error) {
          console.error(`Error closing database connection: ${error}`);
        }
      }
    
      async executeQuery(query) {
        await this.connect();
        const request = this.poolconnection.request();
        const result = await request.query(query);
    
        return result.rowsAffected[0];
      }
    
      async create(data) {
        await this.connect();
        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() {
        await this.connect();
        const request = this.poolconnection.request();
        const result = await request.query(`SELECT * FROM Person`);
    
        return result.recordsets[0];
      }
    
      async read(id) {
        await this.connect();
    
        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) {
        await this.connect();
    
        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) {
        await this.connect();
    
        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];
      }
    }
    

Testa appen lokalt

Appen är redo att testas lokalt. Kontrollera att du är inloggad på Azure Cloud i Visual Studio Code med samma konto som du angav som administratör för databasen.

  1. Kör programmet med följande kommando. Appen startar på port 3000.

    NODE_ENV=development node index.js
    

    Tabellen Person skapas i databasen när du kör det här programmet.

  2. I en webbläsare navigerar du till OpenAPI-utforskaren på http://localhost:3000.

  3. På sidan Swagger-användargränssnitt expanderar du POST-metoden och väljer Prova.

  4. Ändra JSON-exemplet så att det innehåller värden för egenskaperna. ID-egenskapen ignoreras.

    A screenshot showing how to test the API.

  5. Välj Kör för att lägga till en ny post i databasen. API:et returnerar ett lyckat svar.

  6. Expandera GET-metoden på swagger-användargränssnittssidan och välj Prova. Välj Kör och den person som du nyss skapade returneras.

Distribuera till Azure App Service

Appen är redo att distribueras till Azure. Visual Studio Code kan skapa en Azure App Service och distribuera ditt program i ett enda arbetsflöde.

  1. Kontrollera att appen har stoppats.

  2. Logga in på Azure, om du inte redan har gjort det, genom att välja kommandot Azure: Logga in på Azure Cloud i kommandopaletten (Ctrl + Skift + P)

  3. I Azure Explorer-fönstret i Visual Studio Code högerklickar du på Noden App Services och väljer Skapa ny webbapp (avancerat)..

  4. Använd följande tabell för att skapa App Service:

    Prompt Värde
    Ange ett globalt unikt namn för den nya webbappen. Ange en fråga, till exempel azure-sql-passwordless. Efterpenna en unik sträng, till exempel 123.
    Välj en resursgrupp för nya resurser. Välj +Skapa en ny resursgrupp och välj sedan standardnamnet.
    Välj en körningsstack. Välj en LTS-version av Node.js stacken.
    Välj ett operativsystem. Välj Linux.
    Välj en plats för nya resurser. Välj en plats nära dig.
    Välj en Linux App Service-plan. Välj Skapa ny App Service-plan. Välj sedan standardnamnet.
    Välj en prisnivå. Välj Kostnadsfri (F1).
    Välj en Application Insights-resurs för din app. Välj Hoppa över för tillfället.
  5. Vänta tills meddelandet om att appen har skapats innan du fortsätter.

  6. I Azure Explorer expanderar du Noden App Services och högerklickar på den nya appen.

  7. Välj Distribuera till webbapp.

    Screenshot of Visual Studio Code in the Azure explorer with the Deploy to Web App highlighted.

  8. Välj rotmappen för JavaScript-projektet.

  9. När popup-fönstret Visual Studio Code visas väljer du Distribuera.

När distributionen är klar fungerar inte appen korrekt i Azure. Du måste fortfarande konfigurera den säkra anslutningen mellan App Service och SQL-databasen för att hämta dina data.

Anslut App Service till Azure SQL Database

Följande steg krävs för att ansluta App Service-instansen till Azure SQL Database:

  1. Skapa en hanterad identitet för App Service.
  2. Skapa en SQL-databasanvändare och associera den med den hanterade App Service-identiteten.
  3. Tilldela SQL-roller till databasanvändaren som tillåter läs-, skriv- och potentiellt andra behörigheter.

Det finns flera tillgängliga verktyg för att implementera följande steg:

Tjänst Anslut eller är ett verktyg som effektiviserar autentiserade anslutningar mellan olika tjänster i Azure. Tjänst Anslut eller stöder för närvarande anslutning av en App Service till en Azure SQL-databas via Azure CLI med hjälp av az webapp connection create sql kommandot . Det här enkla kommandot slutför de tre steg som nämns ovan åt dig.

Skapa den hanterade identiteten med Service Anslut or

Kör följande kommando i Azure-portalens Cloud Shell. Cloud Shell har den senaste versionen av Azure CLI. Ersätt variablerna i <> med dina egna värden.

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

Verifiera App Service-appinställningarna

Du kan kontrollera de ändringar som gjorts av Service Anslut eller i App Service-inställningarna.

  1. Högerklicka på Din App Service i Azure Explorer i Visual Studio Code och välj Öppna i portalen.

  2. Gå till identitetssidan för din App Service. Under fliken Systemtilldelat ska Status anges till . Det här värdet innebär att en systemtilldelad hanterad identitet har aktiverats för din app.

  3. Gå till sidan Konfiguration för Din App Service. Under fliken Program Inställningar bör du se flera miljövariabler som redan fanns i mssql-konfigurationsobjektet.

    • AZURE_SQL_SERVER
    • AZURE_SQL_DATABASE
    • AZURE_SQL_PORT
    • AZURE_SQL_AUTHENTICATIONTYPE

    Ta inte bort eller ändra egenskapsnamnen eller -värdena.

Testa det distribuerade programmet

Bläddra till appens URL för att testa att anslutningen till Azure SQL Database fungerar. Du kan hitta url:en för din app på översiktssidan för App Service.

Den person som du skapade lokalt bör visas i webbläsaren. Klar! Ditt program är nu anslutet till Azure SQL Database i både lokala och värdbaserade miljöer.

Dricks

Om du får ett 500 internt serverfel under testningen kan det bero på databasnätverkskonfigurationerna. Kontrollera att den logiska servern har konfigurerats med de inställningar som beskrivs i avsnittet Konfigurera databasen .

Rensa resurserna

När du är klar med arbetet med Azure SQL Database tar du bort resursen för att undvika oavsiktliga kostnader.

  1. I sökfältet i Azure-portalen söker du efter Azure SQL och väljer matchande resultat.

  2. Leta upp och välj databasen i listan över databaser.

  3. På sidan Översikt i azure SQL Database väljer du Ta bort.

  4. På den Azure-sida som du vill ta bort... som öppnas skriver du namnet på databasen för att bekräfta och väljer sedan Ta bort.

Exempelkod

Exempelkoden för det här programmet är tillgänglig på GitHub.

Nästa steg