RESTful Node.js Application with passport-http

2019-09-09 12:09发布

I'm working to get passport-http working with my application to make it comply with RESTful principles.

Right now the default is that the browser prompts the user for a username and password with it's own prompt.

With Node.js and PassportJS is it possible to use my own login form? In the case that a user tries to access a page that they are not authenticated for then I would redirect them to that form. Or is this in itself violating the principles of RESTful design?

3条回答
三岁会撩人
2楼-- · 2019-09-09 12:22

REST defines web services. Services are UI agnostic.

In theory, you should be testing your services with a tool such as fiddler, firebug, postman or something similar.

Your UI choices are completely separate.

If you need someone to be able to authenticate, then you will need to handle the visual presentation of the request to user to authenticate.

If you look at the documentation of passport, they show an example of basic authentication:

app.post('/login', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login'}));

In this case, the authenticate will redirect the user to the page defined at the root of the website if successful, else the user will be redirected to a page served at /login.

In either case, the login attempt is a post method that comes from a page served by the webserver.

passportjs docs

查看更多
放荡不羁爱自由
3楼-- · 2019-09-09 12:39

This is what you need in your server file to create user and password authentication. you need to include the localStategy, configure passport, and use the serialize and deserialize methods. The below works.

var express = require("express");
var app = express();
var passport = require("passport");
var flash = require("connect-flash");
var LocalStrategy = require("passport-local").Strategy;
var mongoose = require("mongoose");
var bodyParser = require("body-parser");
var session = require("express-session");
var cookieParser = require("cookie-parser");

app.use(bodyParser.urlencoded({extended : false}));
app.use(bodyParser.json());

app.use(cookieParser());

app.use(session({
    secret : "keyboard cat",
    resave : false,
    saveUninitialized : true
}))

app.use(flash());

app.use(passport.initialize());
app.use(passport.session());



mongoose.connect("mongodb://localhost/passport", function(){
    console.log("connected")
})

var userSchema = new mongoose.Schema({
    username : String,
    password : String,
})

userSchema.methods.validPassword = function(pwd){
    return (this.password === pwd)
}
var User = mongoose.model("User", userSchema)



passport.use("local", new LocalStrategy(
    function(username, password, done){
        User.findOne({ username : username}, function(err, user){
            if(err){return done(err);}
            if(!user){
                console.log("no user")
                return done(null, false,{message : "Incorrect username."});
            }
            if(!user.validPassword(password)){
                return done(null, false,{message : "Incorrect password."});
            }
            return done(null, user)
        })
    }))

passport.serializeUser(function(user, done){ // change done to cb
    done(null, user);
})

passport.deserializeUser(function(user, done){
    User.findOne(user, function(err, user){
        console.log("myerr" + err)
        done(err, user)
    })
})


app.set("views", "./views");
app.set("view engine", "jade");

app.get("/signup", function(req, res){
    res.render("signup")
})

app.post("/signup", function(req, res){
    User.create({"username" : req.body.username, "password" : req.body.password}, function(err, doc){
        console.log(doc);

    })
    res.redirect("/login")
})

app.get("/login", function(req, res){
    res.render("login")
})

app.post("/login", function(req, res, next){
    passport.authenticate("local", function(err, user, info){
        if(err){return next(err); }
        if(!user){return res.redirect("/login");}
            req.logIn(user, function(err){
                if(err){ return next(err);}
                return res.redirect("/users/" + user.username)
            })
    })(req, res, next);
})

app.get("*", function(req, res){
    res.send("EVERYTHANG")
})

app.listen(3000, function(){
    console.log("listening on 3000")
})

login.jade:

html
    head
        title LogIN
    body
        form(method = "POST", action = "/login")
            label username
            input(type = "text", name = "username")
            br
            label password :
            input(type = "text", name = "password")
            button(type="submit") LogIN

signup.jade:

html
    head
        title signup
    body
        form(method = "POST", action= "/signup")
            label username
            input(type = "text", name = "username")
            br
            label password :
            input(type = "text" , name = "password")
            button(type="submit") Signup
查看更多
放荡不羁爱自由
4楼-- · 2019-09-09 12:44

For REST I would suggest you to use HTTP Basic/Digest authentication with HTTPS and you can use http-auth to implement that:

// Authentication module.
var auth = require('http-auth');
var basic = auth.basic({
    realm: "Simon Area.",
    file: __dirname + "/../data/users.htpasswd" // gevorg:gpass, Sarah:testpass ...
});

// Application setup.
var app = express();

// Setup strategy.
var passport = require('passport');
passport.use(auth.passport(basic));

// Setup route.
app.get('/', passport.authenticate('http', { session: false }), function(req, res) {
    res.end("Welcome to private area - " + req.user + "!");
});

or you can use it without passport:

// Authentication module.
var auth = require('http-auth');
var basic = auth.basic({
    realm: "Simon Area.",
    file: __dirname + "/../data/users.htpasswd" // gevorg:gpass, Sarah:testpass ...
});

// Application setup.
var app = express();
app.use(auth.connect(basic));

// Setup route.
app.get('/', function(req, res){
  res.send("Hello from express - " + req.user + "!");
});
查看更多
登录 后发表回答