A Developer's Guide to Uploading Files to SharePoint with Node.js
Programmatically interacting with SharePoint can significantly enhance your automation capabilities, enabling document backups and seamless integration with your business systems. One of the most common requirements developers face is uploading files directly to a SharePoint document library.
In this comprehensive guide, we'll walk through the entire process—from setting up the proper permissions in Microsoft Entra ID (formerly Azure Active Directory) to creating a Node.js script that authenticates and uploads files to a designated SharePoint folder. We'll utilize app-only authentication with a certificate, which is a highly secure method for server-to-server interactions.
Part 1: Configure Microsoft Entra ID and SharePoint
Before writing any code, we need to configure an application in Microsoft Entra ID to grant our script the necessary permissions and gather essential information from our SharePoint site.
Configure a Microsoft Entra OAuth App
Step 1: Register an Application
First, we'll create a new app registration in Microsoft Entra ID:
- Sign in to the Microsoft Entra Admin Center
- Navigate to Entra ID > App registrations
- Click + New registration
- On the "Register an application" page, enter the following:
- Name: Give your application a descriptive name, such as "SharePoint File Uploader"
- Supported account types: Select "Accounts in this organizational directory only (Single tenant)"
- Redirect URI: Leave this blank for server-to-server applications
- Click Register to create the application
Step 2: Add API Permissions
Once your app is registered, you need to grant it permissions to access SharePoint:
- Navigate to the API permissions pane of your app
- Click Add a permission and select the SharePoint tile
- Choose Application permissions
- Select Sites.FullControl.All and User.Read.All
- After adding the permissions, click Grant Admin Consent for [company name] (this requires the Application Administrator role)
Step 3: Generate a Certificate
We'll use a certificate and private key for authentication. You can generate a self-signed certificate using OpenSSL. If you don't have OpenSSL installed, you can install Git for Windows, which includes Git Bash and OpenSSL.
Open a Git Bash terminal and run the following command to generate a private key and certificate signing request:
openssl req -nodes -newkey pkcs8:2048 -keyout azure-ad.key -out azure-ad.csrNext, create the self-signed x509 certificate from your private key and CSR:
openssl req -new -x509 -key azure-ad.key -out azure-ad.cerStep 4: Upload the Certificate
In your Microsoft Entra app registration, navigate to the Certificates & Secrets pane and upload the azure-ad.cer file you just created.
Step 5: Gather Your Credentials
You now have all the credentials needed for authentication. Make a note of the following:
- Application (client) ID: Available in the Overview pane of your app registration
- Directory (tenant) ID: Also in the Overview pane
- Certificate Thumbprint: Visible in the Certificates & secrets pane after uploading your certificate
- Private Key: The full content of the
azure-ad.keyfile you generated
Gather SharePoint Information
You'll also need the following information about your SharePoint site:
SharePoint Site Domain: This is the domain of your SharePoint site, for example: yourcompany.sharepoint.com
Library and Folder Name:
- Your default document library is typically named "Documents". If you've configured a custom library, note its name.
- Navigate to the SharePoint folder where you want to upload files
- Look at the URL—it often contains an
idparameter like?id=%2FShared%20Documents%2FMy%20Folder - Copy the URL-encoded path and use an online tool to URL-decode it. It will become something like
/Shared Documents/My Folder - Remove the leading slash to get the final folder path:
Shared Documents/My Folder
You should now have all the configuration details ready. Let's start coding!
Part 2: The Node.js Code
Our script will have two main functions: one to acquire an access token from Microsoft Entra ID and another to use that token to upload a file to SharePoint.
Project Setup
First, create a new Node.js project and install the necessary packages:
npm init -y
npm install axios @azure/msal-node
We'll use axios for making HTTP requests and @azure/msal-node for authentication.
The Authentication Function
Create a file named index.js in your Node app directory and add the following code to authenticate with Microsoft Entra ID:
const msal = require('@azure/msal-node');
const axios = require('axios');
const fs = require('fs');
const path = require('path');
/**
* Acquires an authentication token from Microsoft Entra ID.
* @param {object} config - The configuration object.
* @returns {Promise<string>} The access token.
*/
async function getToken(config) {
const msalConfig = {
auth: {
clientId: config.clientId,
authority: `https://login.microsoftonline.com/${config.tenantId}`,
clientCertificate: {
thumbprint: config.certificateThumbprint,
privateKey: config.privateKey,
}
}
};
const client = new msal.ConfidentialClientApplication(msalConfig);
const tokenRequest = {
scopes: [`https://${config.sharepointSiteDomain}/.default`]
};
try {
const response = await client.acquireTokenByClientCredential(tokenRequest);
return response.accessToken;
} catch (error) {
console.error('Error acquiring token:', error.message);
throw error;
}
}
This function uses the Microsoft Authentication Library (MSAL) for Node to get an access token using the client ID, tenant ID, certificate thumbprint, and private key you gathered earlier.
The File Upload Function
Next, add the upload function that takes an access token and a file stream and uploads the file to the specified SharePoint folder:
/**
* Uploads a file stream to SharePoint.
* @param {object} config - The configuration object.
* @param {string} accessToken - The authentication token.
* @param {ReadableStream} dataStream - The file stream to upload.
* @param {string} fileName - The name for the uploaded file.
* @param {number} fileSize - The size of the file in bytes.
* @returns {Promise<object>} The response data from SharePoint.
*/
async function uploadFile(config, accessToken, dataStream, fileName, fileSize) {
const sharepointBaseUri = `https://${config.sharepointSiteDomain}/_api/web`;
const uploadUrl = `${sharepointBaseUri}/GetFolderByServerRelativeUrl('${config.folder}')/Files/Add(url='${fileName}', overwrite=true)`;
const axiosConfig = {
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/octet-stream',
'Content-Length': fileSize
}
};
try {
const response = await axios.post(uploadUrl, dataStream, axiosConfig);
console.log('File uploaded successfully!');
return response.data;
} catch (error) {
console.error('Error uploading file:', error.response ? error.response.data : error.message);
throw error;
}
}
The SharePoint REST API endpoint we're using is _api/web/GetFolderByServerRelativeUrl('Your Folder Path')/Files/Add(url='filename.txt', overwrite=true).
Putting It All Together
Now, let's create the main script to run the process. Add the following code to your index.js file:
// --- Main execution ---
async function run() {
// WARNING: In a real application, use a secure way to store and access credentials.
// Do not hardcode them directly in the source code.
const config = {
clientId: "YOUR_CLIENT_ID",
tenantId: "YOUR_TENANT_ID",
sharepointSiteDomain: "yourcompany.sharepoint.com",
privateKey: fs.readFileSync("path/to/your/azure-ad.key", "utf8"),
certificateThumbprint: "YOUR_CERTIFICATE_THUMBPRINT",
library: "Documents",
folder: "Shared Documents/My Folder" // The path you determined earlier
};
const filePath = path.join(__dirname, 'sample.txt');
const fileName = path.basename(filePath);
const fileStats = fs.statSync(filePath);
const fileSize = fileStats.size;
const fileStream = fs.createReadStream(filePath);
try {
// 1. Get authentication token
const accessToken = await getToken(config);
console.log('Successfully acquired access token.');
// 2. Upload the file
const uploadResult = await uploadFile(config, accessToken, fileStream, fileName, fileSize);
console.log('SharePoint upload response:', uploadResult);
} catch (error) {
console.error('An error occurred during the process.');
}
}
// Create a dummy file for testing
fs.writeFileSync('sample.txt', 'This is a test file for SharePoint upload.');
run();
Remember to replace the placeholder values in the config object with your actual credentials. Important: In a production environment, never hardcode credentials directly in your source code. Use environment variables or a secure credential management system.
Running the Script
To run this script, open a terminal, navigate to your Node app directory, and execute:
node index.jsIf everything is configured correctly, you should see a sample.txt file appear in your SharePoint folder!
What's Next?
This guide provides a solid foundation for interacting with the SharePoint REST API using Node.js. You can expand on this implementation to:
- Add metadata to uploaded files
- Download files from SharePoint
- Manage list items and folders
- Implement error handling and retry logic
- Add support for large file uploads using chunking
- Create, update, or delete documents programmatically
By mastering these techniques, you'll unlock a wide range of integration possibilities for your applications, enabling seamless document management and workflow automation across your organization's SharePoint environment.
Security Best Practices
Before deploying your solution to production, keep these security considerations in mind:
- Never commit credentials to version control: Use environment variables or Azure Key Vault to store sensitive information
- Implement proper error handling: Avoid exposing sensitive information in error messages
- Use the principle of least privilege: Only grant the minimum permissions necessary for your application to function
- Rotate certificates regularly: Set up a process to renew and rotate certificates before they expire
- Monitor and log authentication attempts: Keep track of when and how your application accesses SharePoint
Happy coding, and may your SharePoint integrations be smooth and secure!