Node.jsでSFTPに接続する方法
Node.jsを使ったSFTPへの「接続」、「ファイルのリストアップ」、「アップロード」、「ダウンロード」のやり方をここで学んでみましょう。
この記事を読み終わる頃には、 みなさんは最終的にNode.jsのコードの記述に慣れてSFTP サーバーに接続してやりとりが可能になり、我々のヘルプは要らなくなるでしょう。SFTPは広く使用される標準的なプロトコルであり、ファイルやデータの安全な転送に焦点を当てた安全なプロトコルですが、サーバーとの接続を設定する際に、いくつかのステップを完了させなければいけません。では、いきますよ!
必要事項
初めの一歩:ssh2-sftp-client
は node.js 用の SFTP クライアントで、SSH2 のラッパー(wrapper)として SFTP 関連の機能を高度に抽象化したものです。インストールする準備ができたら、まず以下のコードを手動で実行します:
npm install ssh2-sftp-client@^8.0.0
または、package.json
ファイルを追加し、その中で依存関係を宣言します:
そして、以下を実行します:
{
"dependencies": {
"ssh2-sftp-client": "^8.0.0"
}
}
そして、以下を実行します:
npm install
SFTPへの接続
この記事の例として、SFTPTOGO_URL という環境変数を使います。この環境変数には、SFTP サーバーに接続するために必要なすべての情報が、次のようなURI 形式で含まれています: sftp://user:password@host. この変数は URI.parse を使って URI の部分を抽出し、リモートサーバーのホストキーは~/.ssh/known_hosts
を使ってデフォルトで検証されます。
let Client = require('ssh2-sftp-client');
class SFTPClient {
constructor() {
this.client = new Client();
}
async connect(options) {
console.log(`Connecting to ${options.host}:${options.port}`);
try {
await this.client.connect(options);
} catch (err) {
console.log('Failed to connect:', err);
}
}
async disconnect() {
await this.client.end();
}
}
ファイルの一覧表示
接続が確立されると、リモート SFTP サーバ上のファイルを一覧表示するのにそれを使うことができます。これは、ssh2-sftp-client の list メソッドを呼び出して返される配列を反復処理することで、path 引数で見つかったファイルに対応することができます。この例では、ラッパー関数がリモートパスで見つかったファイルを単純に出力しています。
async listFiles(remoteDir, fileGlob) {
console.log(`Listing ${remoteDir} ...`);
let fileObjects;
try {
fileObjects = await this.client.list(remoteDir, fileGlob);
} catch (err) {
console.log('Listing failed:', err);
}
const fileNames = [];
for (const file of fileObjects) {
if (file.type === 'd') {
console.log(`${new Date(file.modifyTime).toISOString()} PRE ${file.name}`);
} else {
console.log(`${new Date(file.modifyTime).toISOString()} ${file.size} ${file.name}`);
}
fileNames.push(file.name);
}
return fileNames;
}
ファイルのアップロード
次のステップは、ファイルのアップロードです。クライアントオブジェクトのput
関数を使用して、ローカルファイルのパスとリモートパスを渡します (アップロード後にファイルもリモートパスに置かれるはずです)。関数呼び出しは次のようになります: await client.uploadFile("./local.txt", "./remote.txt");
async uploadFile(localFile, remoteFile) {
console.log(`Uploading ${localFile} to ${remoteFile} ...`);
try {
await this.client.put(localFile, remoteFile);
} catch (err) {
console.error('Uploading failed:', err);
}
}
ファイルのダウンロード
プロセスの締めは、ファイルのダウンロードです。クライアントオブジェクトのget
関数を使い、リモートファイルのパスと、ダウンロードしたファイルを格納するローカルパスを渡します。これは、次のように関数を呼び出すことになります:await client.downloadFile("./remote.txt", "./download.txt");
async downloadFile(remoteFile, localFile) {
console.log(`Downloading ${remoteFile} to ${localFile} ...`);
try {
await this.client.get(remoteFile, localFile);
} catch (err) {
console.error('Downloading failed:', err);
}
}
全体像
以上の手順を踏まえて、プロセスは完了です! 最後に、プログラムを最初から最後まで通して実行したい場合は、次のコードをコピーしてmain.js
として保存してください:
// sftp.js
//
// Use this sample code to connect to your SFTP To Go server and run some file operations using Node.js.
//
// 1) Paste this code into a new file (sftp.js)
//
// 2) Install dependencies
// npm install ssh2-sftp-client@^8.0.0
//
// 3) Run the script
// node sftp.js
//
// Compatible with Node.js >= v12
// Using ssh2-sftp-client v8.0.0
let Client = require('ssh2-sftp-client');
class SFTPClient {
constructor() {
this.client = new Client();
}
async connect(options) {
console.log(`Connecting to ${options.host}:${options.port}`);
try {
await this.client.connect(options);
} catch (err) {
console.log('Failed to connect:', err);
}
}
async disconnect() {
await this.client.end();
}
async listFiles(remoteDir, fileGlob) {
console.log(`Listing ${remoteDir} ...`);
let fileObjects;
try {
fileObjects = await this.client.list(remoteDir, fileGlob);
} catch (err) {
console.log('Listing failed:', err);
}
const fileNames = [];
for (const file of fileObjects) {
if (file.type === 'd') {
console.log(`${new Date(file.modifyTime).toISOString()} PRE ${file.name}`);
} else {
console.log(`${new Date(file.modifyTime).toISOString()} ${file.size} ${file.name}`);
}
fileNames.push(file.name);
}
return fileNames;
}
async uploadFile(localFile, remoteFile) {
console.log(`Uploading ${localFile} to ${remoteFile} ...`);
try {
await this.client.put(localFile, remoteFile);
} catch (err) {
console.error('Uploading failed:', err);
}
}
async downloadFile(remoteFile, localFile) {
console.log(`Downloading ${remoteFile} to ${localFile} ...`);
try {
await this.client.get(remoteFile, localFile);
} catch (err) {
console.error('Downloading failed:', err);
}
}
async deleteFile(remoteFile) {
console.log(`Deleting ${remoteFile}`);
try {
await this.client.delete(remoteFile);
} catch (err) {
console.error('Deleting failed:', err);
}
}
}
(async () => {
const parsedURL = new URL(process.env.SFTPTOGO_URL);
const port = parsedURL.port || 22;
const { host, username, password } = parsedURL;
//* Open the connection
const client = new SFTPClient();
await client.connect({ host, port, username, password });
//* List working directory files
await client.listFiles(".");
//* Upload local file to remote file
await client.uploadFile("./local.txt", "./remote.txt");
//* Download remote file to local file
await client.downloadFile("./remote.txt", "./download.txt");
//* Delete remote file
await client.deleteFile("./remote.txt");
//* Close the connection
await client.disconnect();
})();
最後に、コマンドで実行します:
node main.js
やりました!Node.jsを使ったSFTPへの接続ができました!
その他コードサンプルはGithubでご覧ください。