session stored in MongoDB

1. Based session of registration, login, logout

session stored in the database

New user.js, add usersmongoose model

var mongoose = require('mongoose')
var Schema = mongoose.Schema

var User = new Schema({
    username: {
        type: String,
        required: true,
        unique: true
    },
    password: {
        type: String,
        required: true
    },
    admin: {
        type: Boolean,
        default: false
    }
})

module.exports = mongoose.model('User', User)

Achieve registration, login, logout function

New users.jsfile

var express = require('express')
const bodyParser = require('body-parser')
var User = require('user.js')

var router = express.Router()
router.use(bodyParser.json())

router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

router.post('/signup', (req, res, next) => {
    User.findOne({username: req.body.username})
    .then((user) => {
        if (user != null) {	// 注册用户已存在
            var err = new Error('User ' + req.body.username + ' already exists!')
            err.status = 403
            next(err)
        } else {	// 没有该用户
            return User.create({
                username: req.body.username,
                password: req.body.password
            })
        }
    })
    .then((user) => {
        res.statusCode = 200
        res.setHeader('Content-Type', 'application/json')
        res.json({status: 'Registration Successful!', user: user})
    }, (err) => next(err))
    .catch((err) => next(err))
})

router.post('/login', (req, res, next) => {
    
    if(!req.session.user) {
        var authHeader = req.headers.authorization
        
        if (!authHeader) {
            var err = new Error('You are not authenticated!')
            res.setHeader('WWW-Authenticate', 'Basic')
            err.status = 401
            return next(err)
        }
        
        var auth = new Buffer.from(authHeader.split(' ')[1], 'base64').toString().split(':')
        var username = auth[0]
        var password = auth[1]
        
        User.findOne({username: username})
        .then((user) => {
            if (user === null) {
                var err = new Error('User ' + username + ' does not exist!')
                err.status = 403
                return next(err)
            } else if (user.password !== password) {
                var err = new Error('Your password is incorrect!')
                err.status = 403
                return next(err)
            } else if(user.username === username && user.password === password) {
                req.session.user = 'authenticated'
                req.statusCode = 200
                res.setHeader('Content-Type', 'text/plain')
                res.end('You are authenticated!')
            }
        })
        .catch((err) => next(err))
    } else {
        res.statusCode = 200
        res.setHeader('Content-Type', 'text/plain')
        res.end('You are authenticated!')
    }
})

router.get('/logout', (req, res) => {
    if (req.session) {
        req.session.destroy()	// 删除session
        res.clearCookie('session-id')	// 清除客户端的cookie
        res.redirect('/')	// 重定向到应用主页
    } else {
        var err = new Error('You are not logged in!')
        err.status = 403
        next(err)
    }
})

changeapp.js

...
app.use('/', indexRouter)
app.use('/users', usersRouter)

function basicAuth(req, res, next) {
    if (!req.session.user) {
        var err = new Error('You are not authenticated!')
        err.status = 403
        return next(err)
    } else {
        if (req.session.user === 'authenticated') {
            next()
        } else {
            var err = new Error('You are not authenticated!')
            err.status = 403
            return next(err)
        }
    }
}
...

2. Passport redundant code optimization

As the above code has many repeated error checking code and repeat the authentication operation, using Passportthe central parity simplified. PassportIt supports different authentication policies, such as OpenID, OAuth, OAuth2.0 and so on. Here, we use Local Strategyto simplify the authentication username and password registered.

Updating user.js, using passport-local-mongoosemodules to simplify usernameand passwordstorage

var passportLocalMongoose = require('passport-local-mongoose')

var User = new Schema({
    admin: {
    	type: Boolean,
    	default: false    
    }
})

User.plugin(passportLocalMongoose)

passport-local-mongooseplugin adds in the username and a encrypted way of storing the password. The password hash registered users encrypted within our user model. Use saltof password encryption, saltis used to perform a cryptographic hashrandom string operation. By storing the password hash encrypted in the database, the original real password is not stored. When a user using a user name and password for authentication by password hashafter, to compare with the password stored in the database.

Therefore, Passport-Local-Mongoosein user modelthe method of adding authentication, authentication is automated; based on user name and password Local Strategyby the authentication method user.authenticateto be used directly.

User name test, password password, for example, stored in the content mongoDB as follows:

{
        "_id" : ObjectId("5e69d49249cd2322286205b6"),
        "admin" : false,
        "username" : "test",
        "salt" : "706639aa4b1d0627629ca0372e3e945189c6d2c6f534dcead55518d13200127c",
        "hash" : "e9141ec79f2a0bcab0af3b4bc337c76b635e36f5cc3727f3d71e24224e559dda87e3e3e5f309d4220c50e1bc0fc10d2d78d007004e0076e81e43a9b05c3393bce5ca7f4de65bef0c40c4e9383aade96263a5a56ca81c9992e859e7e9f5daab2811df49fa897b731d313769c2f3bb2a73f7dd8bbb3c14b3bcf5088c57cb1439db03238f1d542dc56008b067f0061c5f0d91f0ce89c053180630c2e086ebb6fb7f5a26a67a4e5cabe63887beec82af6e757ebf945d727564ee09494d05f3b5fb05e33e718c01e44e7cef10344dd6b2ee02da9717ac410c8259ae752acf8d97e931cc6be2d32981af6c0a24c51fcdbde44dc44bb220abe09407dfadd5c6d3d7a5699ea35db46a3acb0e6881cca77ba2802a75e97f9be8c719792dfc9847e3f0af1b97a0152f1d772eea4c30a0a18e9dc5621bdab77255e958f509402aeb9a2b8238d78e72c46f3b08cb76425aa5ebcdbe80ec7541c3b6b394529be98eed96be5622366710db7388c599d3412dea143b233da9e429ded07bbd1159e41b8ab96a73f79ab15e5734a961c13e276445a8c2f28d315b0e48784918422709763871c1074ccbfc1d9841f88719d529ba0ab90d2d71b4db039213ffb4e072da7787f022564b1ad285b0512e2679edc461286b5c51deb0c0ec9cfbc4a70cecb8e531471a4adeff27b69d0cb0aec4b4f155d3a14d9f03af7f62428b3a895620aa26b3f4a67f09",
        "__v" : 0
}
// 这里可没有存密码

New authenticate.jsfile

var passport = require('passport')
// passport-local支持用户名密码的local strategy认证
var LocalStrategy = require('passport-local').Strategy
var User = require('user')

exports.local = passport.use(new LocalStrategy(User.authenticate()))
passport.serializeUser(User.serializeUser())
passport.deserializeUser(User.deserializeUser())

PassportMiddleware also supports sessions, but the user information to be serialized and sessionthe information stored in the server, receiving the request, the user information need deserialized from sessionthe extracted information. Passport-Local-MongoosePlugin serializeUserand deserializeUsersupport serialization and de-serialization operation.

Change the users.jsfile

...
var passport = require('passport')
...

router.post('/signup', (req, res, next) => {
    User.register(new User({username: req.body.username}), req.body.password, (err, user) => {
        if (err) {
            res.statusCode = 500
            res.setHeader('Content-Type', 'application/json')
            res.json({err: err})
        } else {
            passport.authenticate('local')(req, res, () => {
                res.statusCode = 200
                res.setHeader('Content-Type', 'application/json')
                res.json({success: true, status: 'Registration Successful!'})
            })
        }
    })
})

router.post('/login', passport.authenticate('local'), (req, res) => {
    res.statusCode = 200
    res.setHeader('Content-Type', 'application/json')
    res.json({success: true, status: 'You are successfully logged in!'})
})

changeapp.js

...
var passport = require('passport')
var authenticate = require('./authenticate')

...
app.use(passport.initialize())
app.use(passport.session())
...
function basicAuth(req, res, next) {
    console.log(req.user)
    
    if(!req.user) {
        var err = new Error('You are not authenticated!')
        err.status = 403
        next(err)
    } else {
        next()
    }
}
...

Guess you like

Origin www.cnblogs.com/wydumn/p/12590664.html