Learn how to create a sftp client to connect to your server.

How to create a sftp client with cordova in Android

The SSH File Transfer Protocol (SFTP), also known as the Secure File Transfer Protocol, enables secure file transfer capabilities between networked hosts.

You can create easily a graphical sftp client using this plugin in your Cordova Android App.

Requirements

To use the sftp feature in our Android Cordova app, we will use the cordova-ourcodeworld-sftpplugin. This plugin uses JSCh (JSch - Java Secure Channel - JCraft) under the hood and offers support for the following common tasks :

  • Secure connection.
  • List a remote path.
  • Upload files.
  • Download files.
  • Delete remote file.
  • Use private key to connect.
  • Download/Upload progress indicator.

To install in your project execute the following command :

cordova plugin add https://github.com/sdkcarlos/cordova-ourcodeworld-sftpplugin.git

Read more about the plugin and its documentation here. After the installation, a global variable will be available (after the ondeviceready event of cordova) in the window named : OurCodeWorldSFTP.

This plugin is only functional for Android.

Implementing the sftp client

You need to follow these steps in order to use the plugin correctly :

  1. Create a SFTP Client.
  2. Use the created client to execute all the provided tasks of the plugin.

To create a client use the createSFTPClient method :

/**
 * A client object to download/upload/delete files using SFTP.
 *
 * return {Object}
 */
var client = OurCodeWorldSFTP.createSFTPClient();

Now that we have a client, give the properly credentials to start using the plugin.

If you use a private key :

// Remote path to list
var pathToList = "/var/www/vhosts/myproject";
var myCredential = {
    //or use the ip instead
    //url: "127.0.0.1 etc..."
    url: "myserver.something.com",
    username : null,
    password : null,
    // The path to the .pub local file in your device
    privateKeyPath : "/storage/emulated/0/id_dsa.pub"
};

client.setCredentials(myCredential.url, myCredential.username, myCredential.password);
client.setPath(pathToList);
client.setIdentity(myCredential.privateKeyPath);

Or if you use an username and password :

// Remote path to list
var pathToList = "/var/www/vhosts/myproject";
var myCredential = {
    //or use the ip instead
    //url: "127.0.0.1 etc..."
    url: "myserver.something.com",
    username : "root",
    password : "rootpassword",
};

client.setCredentials(myCredential.url, myCredential.username, myCredential.password);
client.setPath(pathToList);

If you want to increase the security of the connection (and prevent MITM attacks), add a known_hosts file to the client using the setKnownHosts method which expects the path of the known hosts file in the device as first parameter.

client.setKnownHosts("/storage/emulated/0/known_hosts");

Now that the credentials are valid, you can use any of the tasks that the plugin provides.

List a path

List a path using the list method (note that the path has been set using the setPath method in the previous code, you can dinamically change it using that method): 

/**
 * Receives an array with objects with all the content of a path (files and folders)
 */
var success = function(data) {
    console.info(data);
    /**
    Outputs : 
    [
        {
            name:"Folder/File name",
            filepath: "/var/www/vhosts/myproject/something.txt",
            isDir:false, // is Folder = true, is File = false
            isLink:false,
            size:"123", // bytes
            permissions: "????",
            permissions_string:"xxxxx",
        }
    ];
    */
}


var failure = function(e) {
    console.error(e);
}

client.list(success, failure);

Download a file and show progress

To download a file, use the downloadFile method of the client. This function expects as first parameter the remote path of the file and as second parameter the destination file on the device and finally the callbacks.

Note that the path to the local file doesn't use the file:// prefix. Use the relative path instead, Android FileURI scheme is not supported.

client.downloadFile("/var/www/vhosts/myproject/file.txt","/storage/emulated/0/file.txt",{
    success:function(download){
        // see the object info
        console.log(download);

        // If the download has been finished
        if(download.finished == true){
            console.info("The file has been succesfully downloaded");
        // Else is stills being downloaded
        }else{
            //Display the progress
            console.log("Progress download : "+download.progress+"%. "+ download.bytesprogress +" bytes downloaded of " + download.filesizebytes + "total");
        }
    },
    error:function(er){
        console.error(er);
    }
});

Upload a file and show progress

To upload a file use the uploadFile method of the client. This function expects as first parameter the path of the file on the device and as a second parameters the destination file on the remove server and finally the callbacks.

client.uploadFile("/storage/emulated/0/file.txt","/var/www/vhosts/myproject/file.txt",{
    success:function(upload){
        // see the object info
        console.log(upload);

        // if the file has been uploaded
        if(upload.finished == true){
            console.info("The file has been succesfully uploaded");
        }else{
            //Display the progress as it still being downloaded
            console.log("Progress upload : "+upload.progress+"%. "+ upload.bytesprogress +" bytes uploaded of " + upload.filesizebytes + "total");
        }
    },
    error:function(er){
        console.error(er);
    }
});

Delete a file

To delete a file, use the removeFile method of the client. This function expects as first parameter the remote path of the file (in the server) and finally the callbacks.

client.removeFile("/var/www/vhosts/myproject/file.txt",{
    success:function(removed){
        // see the object info
        console.log(removed);

        if(download.deleted == true){
            console.log("File removed from the server");
        }
    },
    error:function(er){
        // snap ! An error :( maybe doesnt exist?
        console.error(er);
    }
});

Have fun


Senior Software Engineer at Software Medico. Interested in programming since he was 14 years old, Carlos is a self-taught programmer and founder and author of most of the articles at Our Code World.

Sponsors