Giter Site home page Giter Site logo

meancheats's Introduction

Node

Basic Node Configuration (package.json)

Node apps are configured via a package.json file. This is where you set the name, version, repository, author, and package dependancies. The format of the file is an object literal, where properties are defined via a key value pair relationship. The key Main tells node which file to use to start the application.

package.json example

    {
    "name" ; "app-name",
    "version" : '1.0.0',
    "description": "best app ever",
    "main": 'server.js',
    "repository": {
      "type" : 'git',
      "url" : "https://github.com/bestappever",
    },
    "dependancies": {
      "express" : "version #"
      "mongoose": "version #"
    },
    "author" : "Liam Neeson"
    }

Installing Packages

Packages can be installed by manually writing them in the package.json file, or through the command line. When installing with the command line make sure to use the --save modifier to add the package to package.json. Packages will be installed into a directory called node_modules, this is where packages live inside Node projects.

Commands

- npm init          //Initialize node project and create package.json file
- node server.js    //Start node application
- nodemon server.js //Start node app with npm package nodemon to watch for file changes
- npm install package-name --save           //Install package via command line.
- npm install package another-package --save //Install multiple packages
- npm install       // Install all dependancies listed in package.json file.

Basic Node HTTP server

Structure
├── nodeApp/
│   ├── index.html
│   ├── server.js
│   ├── package.json

package.json

{
  "name": "http-server",
  "main" : "server.js",
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
      <meta charset="UTF-8">
      <title>Basic Node Server</title>
      <style>
          body{
            text-align:center;
            background:grey;
            padding-top:50px;
            }
      </style>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>

server.js

// get the http and filesystem modules
var http = require('http'), fs = require('fs');
// create our server using the http module
http.createServer(function(req, res) {
  // write to our server. set configuration for the response
  res.writeHead(200, {
    'Content-Type': 'text/html',
    'Access-Control-Allow-Origin' : '*'
});
  // grab the index.html file using fs
var readStream = fs.createReadStream(__dirname + '/index.html');
// send the index.html file to our user
  readStream.pipe(res);
}).listen(3000);
// tell ourselves what's happening
console.log('Visit me at http://localhost:3000');

In server.js the http module is used to create a server and the fs module is used to grab index.html and send it as a response to the user. The server is set to listen on port 3000. View index.html at localhost:3000.


Express Server

Express is a framework for node use to create MVC web apps and REST APIs. Install express using npm install express --save

Structure
├── nodeApp/
│   ├── index.html
│   ├── server.js
│   ├── package.json

package.json

{
  "name": "expressserver",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "author": "your name",
  "license": "ISC",
  "dependencies": {
    "express": "^4.13.3"
  }
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
      <meta charset="UTF-8">
      <title>Basic Node Server</title>
      <style>
          body{
            text-align:center;
            background:grey;
            padding-top:50px;
            }
      </style>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>

server.js

// load the express package and create our app
var express = require('express')
var app = express();

var path = require('path');

//send out index.html file to the user for the home package
app.get('/', function(req, res){
  res.sendFile(path.join(__dirname +'/index.html'));
});

//start the server
app.listen(3000);
console.log('server running on port 3000');

Node Routing with Express

To server multiple pages to users additional routes will be required. The express router can be used to achieve this. The express router provides routing APIs like .use(), .get(), .param(), and .route().

Using the Router(),

express.Router()

Call an instance of express.Router() and define routes on that. For Example in applications an adminRouter is usually created to handle admin specific routes. This is useful because we can create multiple instances of the express router allowing for our basic routes, authenticated routes, and API routes.

var adminRouter = express.Router([options]);
app.use('/admin', adminRouter);
Property Description Default Availability
caseSensitive Enable case sensitivity. Disabled by default, treating “/Foo” and “/foo” as the same.
mergeParams Preserve the req.params values from the parent router. If the parent and the child have conflicting param names, the child’s value take precedence. false 4.5.0+
strict Enable strict routing. Disabled by default, “/foo” and “/foo/” are treated the same by the router.

Basic routes - Express

Structure
├── nodeApp/
│   ├── index.html
│   ├── server.js
│   ├── package.json

package.json

{
  "name": "expressserver",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "author": "your name",
  "license": "ISC",
  "dependencies": {
    "express": "^4.13.3"
  }
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Basic Express Routes</title>
  </head>
  <body>

  </body>
</html>

server.js

//load the express package and create our app
var express = require('express');
var app = express();
var path = require('path');

//send our index.html file to the user for the home package
app.get('/', function(req,res){
  res.sendFile([path.join(__dirname + '/index.html')]);
});

//start the server
app.listen(3000);
console.log("server runninr on port 3000");

// 1. get an instance of the router, 2. apply routes to it, 3. add those routes to our main app

// get an instance of the router
var adminRouter = express.Router();
 adminRouter.get('/', function(req,res){
  res.send('Dashboard');
});

// users page /admin/users
adminRouter.get('/users', function(req, res){
  res.send('Posts')
})
// apply routes to application
app.use('/admin', adminRouter);

Route Middleware - router.use()

Middleware is a way to do something before a request is processed. For example checking if a user is authenticated and logging date for analytics. Make sure you place middleware after your router declaration and before and defined routes. The next() argument is used to tell Express that the middleware function is complete. The order you place your middleware and routes is very important.

adminrouter.use(function(req,res,next){
  // logging each request made to console
  console.log(req.method , req.url);
// continue to the route
  next();
});

Route Parameters - /user/:id

Express can handle route parameters. Route parameters can be used to validate data coming into your application. This could be used to validate a token for a REST API.

//user ID is passed into the url   /admin/users/:name
adminRouter.get('/users/:name', function(req,res){
  res.send('hello'+ req.params.name + '!');
});

Middleware for Parameters - .param()

Creates middleware that will run for a certain route parameter.

adminRouter.param('name' , function(req, res, next, name){
  //do validations http-server

  //once validations done save item in the req

  req.name = name;
  // do the thing
  next();

  });

  //route middleware is acting upon localhost:3000/admin/hello/:name
  //When the /hello/:name route is hit the .param() middleware will be used.

  adminRouter.get('/hello/:name', function(req ,re) {
    res.send('hello' + req.name + '!');
  });

Login Routes - app.route()

routes can be defined on the app variable, like calling express.Router(). This allows you to define multiple actions on a single login route. Routes are applied directly to the main app object.

admin.route('/login')
      // show form localhost:3000/login
    .get(function(req,res){
      res.send('login form');
    });
    // process the form
    .post(function(req,res){
      res.send('processing login form')
    })

Bullets

  • use express.Router() multiple times to define groups of routes
  • apply the express.Router() to a section of the site using app.use()
  • use route middleware to process requests
  • use route middleware to validate parameters using .param()
  • use app.route() to define multiple requests on a route

  • Manual

    Commands

    Rather than making queries to a table like in a traditional SQL database, queries using Mongo will be made to collections of documents. Stored in JSON style. Mongo will not create a database unless you insert information into that database

    Common

    mongod          - connect to Mongo instance
    show databases  - list all databases
    db              - show current database
    use db_name     - select a database
    

    CRUD

    Create: Creates both database and collection if they do not already exist
    
    db.users.save({ name: 'Bob'});                  - save one user
    db.users.save([{name: 'Bob'}, {name: "Tod"}]);  - save multiple users
    
    Read:
    
    db.users.find();              - show all users
    db.users.find({name: 'Bob'}); - find a specific user
    
    Update:
    
    db.users.update({name: 'Bob'}, {name:'Bob Tod'}); - update user value
    
    Delete:
    
    db.users.remove({});           - remove all
    db.users.remove({name:'Bob'}); - remove one
    

    Mongo and Node

    I use the node package mongoose when working with Mongo.

    Connection to a DB using mongoose

    //grab mongoose package
    var mongoose = require('mongoose');
    
    mongoose.connect('mongodb://localhost/db_name')

    RESTful Node API (Application Programming Interface)

    Express will be the node framework used, morgan allows loggin requests to the console, mongoose is an ODM for communication with Mongo, body-parser is used to pull POST content from an HTTP request, and bcrypt is used to has passwords to be stored in a mongo document.

    Structure
    - app/
    ----- models/
    ----------user.js       // user model
    - node_modules/        // dependencies/packages
    - package.json        // app dependencies
    - server.js          // configure application and create routes
    

    package.json

    npm install express morgan mongoose body-parser bcrypt-nodejs --save
    
    {
    "name" ; "nodeApi",
    "version" : '1.0.0',
    "main": 'server.js',
    "dependancies": {
      "express" : "version #",
      "mongoose": "version #",
      "body-parser": "version #",
      "bcrypt-nodejs": "version #",
    }
    }
    

    server.js

    // gettin dem packages
    var express = require('express');
    var app = express();
    var bodyParser = require('body-parser');
    var morgan = require('morgan');
    var mongoose = require('mongoose');
    var port = process.env.PORT || 3000;
    
    //setting up the app
    mongoose.connect('mongodb://localhost/meancheats')
    var User = require('./app/models/user');
    // body-parser for post requests
    app.use(bodyParser.urlencoded({extend: true}));
    app.use(bodyParser.json());
    
    
    //CORS annoyance protection
    app.use(function(req,res,next){
      res.setHeader('Access-Control-Allow-Origin', "*");
      res.setHeader('Access-Control-Allow-Methods','GET, POST');
      res.setHeader('Access-Control-Allow-Headers','X-Requested-With,content-type,Authorization');
      //carry on
      next();
    });
    //gotta see those requests via console
    app.use(morgan('dev'));
    
    //ROUTES API------------------------------------
    
    app.get('/', function(req,res){
      res.send('Home Route Ya')
    });
    
    
    var api = express.Router() //instance of Router
    //api route middleware
    api.use(function(req,res,next){
      console.log('api hit');
      next() //finish route
    })
    api.get("/", function(req,res){
      res.json({important: '/ api route Ya'});
    });
    
    //all api routes will start with /api
    app.use('/api', apiRouter)
    
    //fire up the server
    app.listen(port);
    console.log('server running on port ' + port );

    user.js

    • create Schema setting name, username, and password as Strings
    • setting index and unique prevents the username from being duplicated
    • setting select: false on passwords prevents it from being shown when making db queries
    • .pre() ensures password is hashed before being saved
    • added a passwordCheck method on UserSchema to validate input with stored data
    // grabbing packages
    var mongoose = require('mongoose');
    var Schema = mongoose.Schema;
    var bcrypt = require('bcrypt-nodejs');
    // user schema
    var UserSchema = new Schema({
      name: String,
      username: {type: String, required: true, index: {unique :true}},
      password: {type: String, required: true, select:false}
    })
    // using bcrypt to hash the password before it is saved
    UserSchema.pre('save', function(next){
      var user = this;
    //if user isn't new and password wasn't changed then do not create a hash
      if(!user.isModified('password')) return next();
    // making that hash
      bcrypt.hash(user.password, null, null, function(err, hash){
        if (err) return next(err);
        //setting the hashed pw
        user.password = hash
        next();
      });
    });
    
    // checking input password with hashed to see if they match
    UserSchema.methods.passwordCheck = function(password) {
      var user = this;
    
      return bcrypt.compareSync(password, user.password);
    };
    
    // exporting the model so the rest of the app can use it
    module.exports = mongoose.model('User', userSchema);

    API routes

    Route Verb Action
    /api/usersGETGet all Users
    /api/usersPOSTCreate a user
    /api/users/:user_idGETGet a single user
    /api/users/:user_idPUTUpdate a user
    /api/users/:user_idDELETEDelete a user

    User POST - /api/Users

    server.js below middleware

    // routes that end in /users
    api.route('/users')
      //create user post to localhost:3000/api/users
      .post(function(req,res){
        //instance of User model
    
        var user = new User();
        // set user data to input data
    
        user.name = req.body.name;
        user.username = req.body.username;
        user.password = req.body.password;
        //save the user to mongo, whilst doing the checking of the errors
        user.save(function(err) {
          if (err) {
            console.log(err);
            //if there is an error and its code is 11000 thats a duplicate username
            if(err.code == 11000)
              return res.json({success: false, message: 'A user with that username already exists.'});
            else
                return res.send(err)
          }
              res.json({message: 'User created'});
    
        });
      });

    User GET all - /api/users

    server.js below middleware

    api.route('/users')
      .post(function(req,res) {
        //create a user
      })
      // get all users in the database GET localhost:3000/api/users
      .get(function(req,res){
        User.find(function(err, users){
          if (err) res.send(err)
          //return users if no errors
          res.json(users);
        });
      });

    User Get single - /api/users/:id

    server.js

    api.route('/users/:id')
      //get user with specfic id
      //localhost:3000/api/users/:id
    
      .get(function(req,res){
        User.findById(req.params.id, function(err,user){
          if(err) res.send(err);
    
          //return single user_id
          res.json(user);
        });
      })

    User PUT update - /api/users/:id

    server.js

    api.route('/users/:id')
      .get(function(req,res){
        //get single user
      })
      //update user
      .put(function(req,res){
        //find user by id
        User.findById(req.parms.id , function(err, user) {
          if (err) res.send(err);
          // update the users info only if its new
          if (req.body.name) user.name = req.body.name;
          if (req.body.username) user.username = req.body.username;
          if (req.body.password) user.password = req.body.password;
          // save the updates
          user.save(function(err){
            if (err) res.send(err);
            res.json({message: 'user updated, chyeah'});
          });
        });
      })

    User DELETE remove user - /api/users/:id

    server.js

    api/route('/users/:id')
    .delete(function(req,res){
    User.remove({
      _id: req.params.id
    }).then(function(err,user){
    
      if (err) return res.send(err)
      res.json ({message: "user deleted"});
    })
      })

    Node Authentication - Token Based

    Their are many ways to implement authentication but one of the most widely used is token based auth. The main benefits to token based authentication is the ability to create stateless and scalable servers, mobile application ready, OAuth and added security.

    In traditional server authentication user login information is stored on the server via session, memory or stored disk. The HTTP protocol is stateless meaning if authentication is done based upon that the server would forget who the user is on every new request.

    SERVER VS TOKEN server vs toke

    Why Server based Auth is old school

    Sessions: storing user information in memory can create overhead when many users are authenticating. Scalability: cloud providers start replicating servers to handle application load, having vital information in session memory will limit ability to scale. CORS: could run into problems with forbidden requests. For example when using multiple mobile devices. CSRF: users could be victim to cross-site forgery.

    Why token based Auth is new school cool

    • token based authentication is stateless.
    • no information about the user is stored in server or session
    • no session info means app can scale and add more machines as necessary regardless of where user is logged in.
    • every request after the first will require the token
    • token should be sent in HTTP header
    • to accept requests from all domains using Access-Control-Allow-Origin: *
    • data access permissions can be set on tokens for third party applications.
    1. User Requests Access with Username / Password
    2. Application validates credentials
    3. Application provides a signed token to the client
    4. Client stores that token and sends it along with every request
    5. Server verifies token and responds with data

    Benefits

    Stateless and scalable

    • tokens are stored on client side, stateless and ready to be scaled.
    • can be passed along to any server, useful in load balancing because their is no state or session.
    • token holds the user data

    Security

    • because no cookie is being sent, the feasibility of a CSRF attack drops dramatically.
    • token can be stored in a cookie, cookie is not used to authenticate token inside cookie is.
    • token can expire after a set amount of time, requiring a user to log in again.
    • selective permissions to third party apps.
    • used inside HTTP header when authenticating an API.

    JSON Web Tokens

    • works with many programing languages
    • carry all the information necessary within itself (self contained) jwt

    Header (2 parts)

    the header contains two parts the type (jwt) and the hashing algorithm being used.

    			{
    				"typ" : "JWT",
    				"aig" : "HS256"
    			}
    

    Payload

    The payload contains the information that is being transmitted as well as additional token information.

    Payload

    		 {
    		 "iss": "issuer of the token",
    		 "sub" : "subject of token",
    		 "aud" : "audience of token"
    		 "exp": "experation time of the token",
    		 "nbf": "Defines the time before which the JWT MUST NOT be accepted for processing",
    		 "iat": "The time the JWT was issued. Can be used to determine the age of the JWT",
    		 "jti": "Unique identifier for the JWT. Can be used to prevent the JWT from being replayed. This
    

    is helpful for a one time use token", "name": "Bobby Mcguee", "admin": true }

    Signature

    a hash made up of the following:

    • header
    • payload
    • secret
    • token is sent on every request so there are no CSRF attacks. There is no session based information to manipulate since, there is no session.
    var encodedString = base64UrlEncode(header) + "." + base64UrlEncode(payload);
    
    HMACSHA256(encodedString, 'secret');

    Authenticating Node.js API

    • home page unauthenticated
    • API routes are authenticated
    • login route used to authenticate a user
    • pass in token for auth
    npm install jsonwebtoken --save
    //create and verify tokens
    

    package.json

    {
      "name": "noderestapi",
      "version": "1.0.0",
      "description": "",
      "main": "server.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "start": "node server.js"
      },
      "author": "",
      "license": "ISC",
      "dependencies": {
        "bcrypt-nodejs": "0.0.3",
        "body-parser": "^1.15.0",
        "express": "^4.13.4",
        "mongoose": "^4.4.6",
        "morgan": "^1.7.0"
      }
    }
    

    server.js

    Was tired of token stuff, gunna start up angular and come back to this

    Angular (FRONT-END)

    • "What HTML would have been if it had been designed for web-apps"
    • MVC architecture

    Data-Binding

    data binding allows for a centralized source of data, this allows a developer to move away from injecting data into views. For example with JQuerys (append,val, html). Angular handles injection for you by binding variables in the view and controller.

    Structure

    ├── js/
    │   ├── app.js
    ├── index.html
    

    app.js

    angular.module('angApp',[]);
    .controller('mainController', function() {
    	// binding this to view model
    	var viewModel = this;
    
    	// defining variables on this allows them to be available to your apps views
    
    viewModel.message = "hello world";
    
    viewModel.list = [
    	{name:'Bob', sex:'male'},
    	{name:'Tina', sex:'female'},
    	{name:'Fiona', sex:'female'}
    	];
    });
    <!DOCTYPE html>
    <html ng-app="angApp">
    	<head>
    		<meta charset="utf-8">
    		<title>Angular App Basic</title>
    	</head>
    	<body  ng-controller="mainController as main">
    		<div class="">
    			<h2>{{main.message}}</h2>
    			<p ng-repeat="peeps in main.list">
    				{{peeps.name}}
    				{{peeps.sex}}
    			</p>
    		</div>
    	</body>
    </html>

meancheats's People

Contributors

weberl48 avatar

Stargazers

Manoj avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.