WebFund 2013W Lecture 23: Difference between revisions
No edit summary |
|||
Line 158: | Line 158: | ||
==demo-auth-hash/views/layout.jade== | ==demo-auth-hash/views/layout.jade== | ||
<source lang="javascript"> | <source line lang="javascript"> | ||
doctype 5 | doctype 5 | ||
html | html | ||
Line 197: | Line 197: | ||
==blog-updated/articleprovider-mongodb.js== | ==blog-updated/articleprovider-mongodb.js== | ||
<source lang="javascript"> | <source line lang="javascript"> | ||
var Db = require('mongodb').Db; | var Db = require('mongodb').Db; | ||
var Connection = require('mongodb').Connection; | var Connection = require('mongodb').Connection; |
Revision as of 16:16, 9 April 2013
The final exam will be similar to the midterm. To prepare, make sure you understand the content on the midterm and understand the following code fragments.
Code
demo-auth-hash/app.js
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path')
, bcrypt = require("bcrypt") //hashing algorithm
, MongoStore = require('connect-mongo')(express) //session datastore using mongodb
, mongoose = require('mongoose') //blessed mongodb connector
, User; //User class defined below
//connect to the "users" database
mongoose.connect('mongodb://localhost/users');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
//once the DB connection is open...
db.once('open', function callback () {
//Create a mongoose Schema (document structure)
var userSchema = mongoose.Schema({
username: String,
password: String
});
//Convert this schema into an instantiable "model" Class
User = mongoose.model("User", userSchema);
});
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
//enable cookies
app.use(express.cookieParser());
//setup session management
app.use(express.session({
cookie: {maxAge: 60000 * 20} // 20 minutes
, secret: "Shh... I'm a secret"
, store: new MongoStore({ //use a mongo-connect store
db: "sessions"
})
}));
app.use(app.router);
app.use(require('less-middleware')({ src: __dirname + '/public' }));
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler());
});
app.get('/', function(req, res, next){
//redirect to user page if logged in
if(req.session.username){
res.redirect("/users");
}else{
next();
}
}, routes.index);
app.get('/users', function(req, res, next){
//redirect home if not logged in
if(req.session.username){
next();
}else{
res.redirect("/");
}
}, user.list);
app.post("/register", function(req, res){
var username = req.body.username;
var password = req.body.password;
User.find({username: username}, function(err, users){
//check if the user already exists
if(users.length!=0){
res.redirect("/?error=user already exists");
return;
}
//generate a salt, with 10 rounds (2^10 iterations)
bcrypt.genSalt(10, function(err, salt) {
//hash the given password using the salt we generated
bcrypt.hash(password, salt, function(err, hash) {
//create a new instance of the mongoose User model we defined above
var newUser = new User({
username: username,
password: hash
});
//save() is a magic function from mongoose that saves this user to our DB
newUser.save(function(err, newUser){
res.send("successfully registered user: "+newUser.username);
});
});
});
});
});
app.post("/login", function(req, res){
var username = req.body.username;
var password = req.body.password;
//Search the Database for a User with the given username
User.find({username: username}, function(err, users){
//we couldn't find a user with that name
if(err || users.length==0){
res.redirect("/?error=invalid username or password");
return;
}
var user = users[0];
//compare the hash we have for the user with what this password hashes to
bcrypt.compare(password, user.password, function(err, authenticated){
if(authenticated){
req.session.username = user.username;
res.redirect("/users");
}else{
res.redirect("/?error=invalid username or password");
}
});
});
});
app.post("/logout", function(req, res){
req.session.destroy(function(err){
if(err){
console.log("Error: %s", err);
}
res.redirect("/");
});
});
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
demo-auth-hash/views/layout.jade
doctype 5
html
head
title= title
script(src='/libs/jquery/jquery.min.js')
script(src='/src/home.js')
link(rel='stylesheet', href='/libs/bootstrap/css/bootstrap.min.css')
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content
demo-auth-hash/views/index.jade
extends layout
block content
h1= title
p Welcome to #{title}
- if(error)
div.alert-error #{error}
p Please log in
div
form(action="/login", method="post")
div.control-group.input-append
input(type="text", name="username")
label.add-on(for="username") Username
div.control-group.input-append
input(type="password", name="password")
label.add-on(for="password") Password
button(type="submit") Login
button#register(type="button") Register
blog-updated/articleprovider-mongodb.js
var Db = require('mongodb').Db;
var Connection = require('mongodb').Connection;
var Server = require('mongodb').Server;
var BSON = require('mongodb').BSON;
var ObjectID = require('mongodb').ObjectID;
ArticleProvider = function(host, port) {
this.db= new Db('node-mongo-blog', new Server(host, port, {auto_reconnect: true}), {journal: true});
this.db.open(function(){});
};
//addCommentToArticle
ArticleProvider.prototype.addCommentToArticle = function(articleId, comment, callback) {
this.getCollection(function(error, article_collection) {
if( error ) callback( error );
else {
article_collection.update(
{_id: article_collection.db.bson_serializer.ObjectID.createFromHexString(articleId)},
{"$push": {comments: comment}},
function(error, article){
if( error ) callback(error);
else callback(null, article)
});
}
});
};
//getCollection
ArticleProvider.prototype.getCollection= function(callback) {
this.db.collection('articles', function(error, article_collection) {
if( error ) callback(error);
else callback(null, article_collection);
});
};
//findAll
ArticleProvider.prototype.findAll = function(callback) {
this.getCollection(function(error, article_collection) {
if( error ) callback(error)
else {
article_collection.find().toArray(function(error, results) {
if( error ) callback(error)
else callback(null, results)
});
}
});
};
//findById
ArticleProvider.prototype.findById = function(id, callback) {
this.getCollection(function(error, article_collection) {
if( error ) callback(error)
else {
article_collection.findOne({_id: article_collection.db.bson_serializer.ObjectID.createFromHexString(id)}, function(error, result) {
if( error ) callback(error)
else callback(null, result)
});
}
});
};
//save
ArticleProvider.prototype.save = function(articles, callback) {
this.getCollection(function(error, article_collection) {
if( error ) callback(error)
else {
if( typeof(articles.length)=="undefined")
articles = [articles];
for( var i =0;i< articles.length;i++ ) {
article = articles[i];
article.created_at = new Date();
if( article.comments === undefined ) article.comments = [];
for(var j =0;j< article.comments.length; j++) {
article.comments[j].created_at = new Date();
}
}
article_collection.insert(articles, function() {
callback(null, articles);
});
}
});
};
exports.ArticleProvider = ArticleProvider;