jwt-http
This is http frame work for developing rest api (back end) and also frontend.
Rest api backend responces are served by JSON.
This is a light weight frame work, unopinated supports the middleware for adding functionlites
recomended architure is
dir: app
dir:backend
files/dir:routes //routes of backend
dir:model database connection and bussiness logic
file:conn.js // database connection etc
dir:frontend
dir:HTML
file:index.html
dir:httmlerror
404.html
dir:assets(public folder)
dir:scripts
file:style.css
dir:styles
file:script.js
dir:img
file:img.jpg
file/dir:routes//for front end
index.js
package.json
package-lock.json
node_nodules
for backend routes advise is /backend/** or /api/** so that frontend routes do not conflict
Feutures
- JWT
- user, roles and permssions
- http, https
- GET, POST, PUT, DELETE
- file upload
Requiring the jwt-http
http set up
var app = require("jwt-http");
app.setPort(8002);
https setup
place private key and certificate or public in the project folder
var options = {
key : fs.readFileSync(path.join(__dirname, "/key.pem")),
cert : fs.readFileSync(path.join(__dirname, "/cert.pem"))
}
options ={
key : keyPath,
cert : certPath
}
app.setHttpsServer(options, 8000);
GET method routing
app.getMethod("/umesh", true,function(req, res){
app.httpMsgs.sendJSON(req, res, JSON.stringify(({
name : "Umesh Bilagi",
age : 47,
sex : "male"
}));
});
app.getMethod("/ramya" , true, function(req, res){
app.httpMsgs.sendJSON(req, res, JSON.stringify({
name : "Ramya Bilagi",
age : 35,
sex : "female"
}));
});
POST method routing
app.postMethod("/mypost", true,function(req, res){
var data= querystring.parse(req.body);
var processed_data = JSON.stringify(data)
app.httpMsgs.sendJSON(req, res, processed_data);
});
PUT method routing
app.putMethod("/put", true, function(req, res){
var data = querystring.parse(req.body);
console.log(data);
app.httpMsgs.sendJSON(req, res, {
done : "done"
});
})
DELETE method routing
app.deleteMethod ("/delete/:id", true, function(req, res){
var id = req.params.id
app.httpMsgs.sendJSON(req, res, {
deleted_id : id
});
});
querystring and adding parmeters to url
app.getMethod("/employ/:id", false, function(req, res){
app.httpMsgs.sendJSON(req, res, {"params" : req.params});
});
var emp = function(req, res){
app.httpMsgs.sendJSON(req, res, app.getParsedQuery());
}
app.getMethod("/emp" + app.queryExpression(), true, emp);
Middleware
- Middleware are essentially functions. They process and passes the result to next middleware or final function
- middle ware can manipulate the req and res.
- next(req, res, next) will triger further process next function or middleware.
- Middleware are to be writen before routes declaration starts
- Middleware can be classified into two types generic and specific.
- Generic applies all routes, unless usemiddleware argument is set false while route methods (getMethod, postMethod, putMethod, deleteMethod and renderHTML) is being set.
Middle for all routes (Generic)
app.use(function(req, res, next){
req.property_generic = "generic"
next(req, res, next);
});
Middle ware for selected routes (specific)
var curmiddleware = funtion(req, res, next){
req.property_specific = "specific"
next(req, res, next);
}
app.getMethod("/umesh", false, curmiddleware, function(req, res, next){
app.httpMsgs.sendJSON(req, res, {
name : "Umesh Bilagi",
age : 47,
sex : "male",
middle : req.property_specific
});
});
Front end
Front end assets can also be routed in order to be included in html pages but advice is use public folder method see below
app.sendFile(url, contentType ,path);
- url is route
- contentType is Content-Type i.e text/html, text/javascript, text/css
- path is actual place of file
app.sendFile("/index","text/html", __dirname + "/index.html");
app.sendFile("/bundle.js","text/javascript", __dirname + "/javascript");
app.sendFile("/styles","text/css", __dirname + "/style.css");
Render HTML using inbult templeting engine
use partials like header.html and footer.html similiar to wordpress app.render.addPartials
example below
{{get(header)}}
{{get(footer)}}
for detailed documentation of render html check npm render-html-async node module
app.renderHTML(url, path, useMiddleware, specificMiddleWare);
- url is route
- path is actual place of file
- middlWare
//url for index.html see below
http://localhost:9000/index?name=umesh&age=45&sex=male&occ=doctor
//route for index.html see below
app.renderHTML("/index" + app.queryExpression() , __dirname + "/index.html", true, specific_
middleWare);
// below is index.html page
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>{{name}}</h1>
<h1>{{age}}</h1>
<h1>{{sex}}</h1>
<h1>{{occ}}</h1>
</body>
</html>
Login Code useing middleware
Login route and its middle ware
var loginMiddleWareMethod = function(req, res, next){
var data = queryString.parse(req.body);
var user = data.user;
var password = data.password;
var login;
if(login){
next(req, res, next);
}else{
app.httpMsgs.send500(req, res, "invalid user and password", false);
return false
}
}
app.setLoginRoute(loginMiddleWareMethod,"topsecret", 1);
app.setlogout();
{
"user": "username",
"createdDate": "2018-05-25T05:21:01.482Z",
"expireInMinutes": 1
}
app.getMethod("/ramya",true, app.validate_login, function (req, res, next){
app.httpMsgs.sendJSON(req, res, ({
name : "Ramya Bilagi",
age : 35,
sex : "female"
}));
});
user-groups-roles
user-groups-roles can be used in these senriores.
- Inside route
- Inside the model (business logic)
process of setting
- create roles (common for both scenarios)
exmple
createNewRole("admin");
- create previlages
- set add privileges to roles
Inside route
Createing privileges
ex: createNewPrivileges(["/article", "POST"], "article", false);
add privilges to roles
ex: addPrivilegeToRole("admin", ["/article", "POST"], true);
From above code Login Code useing middleware
app.validate_login middleware returns req.jwt this contains a payload with user.
Access role of the user from your database.
call this function getRoleRoutePrivilegeValue = (role, url, method)
. This returns the value of the route privilege
Inside the model (bussiness logic).
Createing privileges
ex: createNewPrivileges("secureFunctionPrivilege", "this is secured function", false);
add privilges to roles
ex: addPrivilegeToRole("admin", "secureFunctionPrivilege", true);
.
call this function inside business logicgetRolePrivilegeValue = (role, privilge)
. This returns the value of the privilege
Assets routes creatation
assets
folder conatins the script files, css file or image files- This can contain sub folder inside.
- routes generated will be
/style.css
for a file just inside assets folder and for file inside subfolder it will /subfolder/javascript.js
- Image can also included inside this assets folder
app.setAssetDirRoutes(__dirname + "/assets");
setPublicFolder
This method set the public folder simlier to setAssetDirRoutes. but files can be added dynamically hear (i.e at run time) like uploading files and routes creation for them
- this method is for setting the public folder
- adding uploads, javascript file, images styles etc
- example app.setPublicFolder('public', __dirname)
- routes for accessing files from public folder exmple http://www.example.com/public/subfolder/file.type
Cookie
First create cookistring
var cookieString =setCookieString(req, res, name, value, expires ,maxAge, httponly=true,https=false, SameSite="Strict");
call setcookie method
app.httpMsgs.setCookie(req, res, cookieString, data="", resEnd=true);
call getcookie method access cookie
var cuCokkie = app.httpMsgs.getCookie(req, res, curCookie);
httpMsgs
kindly check about this module from this link http-msgs
handling 404
create route for these and by this method setRoute404
create file inthe mentioned path
app.setHTML404(__dirname + "/404.html");
file Upload
use third party uploader like multer or formidable
file upload use enctype="multipart/form-data"
example of formidable
app.postMethod("/upload", true, function(req, res, next){
var form = new formidable.IncomingForm();
form.parse(req);
form.on('fileBegin', function (name, file){
file.path = __dirname + '/uploads/' + file.name;
});
form.on('file', function (name, file){
console.log('Uploaded ' + file.name);
});
form.on("error", function(error){
app.httpMsgs.send500(req, res, error);
})
form.on("end", function(){
app.httpMsgs.sendHTML(req, res, "uploded");
});
});
To do
- sanitazation and XSS
- HTTP2