Last active
March 28, 2020 19:54
-
-
Save callmephilip/428f11a1bb28cace7fa8ba4b066c06de to your computer and use it in GitHub Desktop.
Passport.js + Meteor accounts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// http://blog.thebakery.io/meteor-accounts-auth-with-passportjs/ | |
import bcrypt from 'bcrypt'; | |
import crypto from 'crypto'; | |
import express from 'express'; | |
import mongoose from 'mongoose'; | |
import passport from 'passport'; | |
import { Strategy as LocalStrategy } from 'passport-local'; | |
import { BasicStrategy } from 'passport-http'; | |
const User = mongoose.model('users', new mongoose.Schema({ | |
_id: String, | |
}, { | |
collection: 'users', | |
})); | |
function comparePasswords(password, hash, callback) { | |
bcrypt.compare(crypto.createHash('sha256').update(password).digest('hex'), hash, callback); | |
} | |
function deserializeUserPassport(id, done) { | |
User.findOne({ _id: id }, (err, userModel) => { | |
if (err) { | |
done(err); | |
} else { | |
if (!userModel) { | |
done(); | |
return; | |
} | |
done(null, userModel.toJSON()); | |
} | |
}); | |
} | |
function getUserPassport(username, password, done) { | |
User.findOne({ | |
'emails.address': username, | |
}, (findError, userModel) => { | |
if (findError) { | |
return done(findError); | |
} | |
if (!userModel) { | |
return done(null, false, { message: 'Incorrect username.' }); | |
} | |
const user = userModel.toJSON(); | |
comparePasswords(password, user.services.password.bcrypt, (hashError, goodPassword) => { | |
if (hashError) { | |
return done(hashError); | |
} | |
if (!goodPassword) { | |
return done(null, false, { message: 'Incorrect password.' }); | |
} | |
return done(null, user); | |
}); | |
}); | |
} | |
passport.serializeUser((user, done) => done(null, user._id)); | |
passport.deserializeUser(deserializeUserPassport); | |
// Passport auth strategy for basic username + password setup | |
// if you only want to use this server as an API endpoint, you can just remove this | |
// and keep BasicStrategy below | |
passport.use(new LocalStrategy(getUserPassport)); | |
// Passport auth strategy for Basic Auth | |
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization | |
passport.use(new BasicStrategy(getUserPassport)); | |
const app = express(); | |
app.use(require('cookie-parser')()); | |
app.use(require('body-parser').urlencoded({ extended: true })); | |
app.use(require('express-session')({ secret: 'keyboard cat', resave: true, saveUninitialized: true })); | |
app.use(passport.initialize()); | |
app.use(passport.session()); | |
const port = process.env.PORT || 3007; | |
app.get('/', (req, res) => { | |
// When logged in user object is attached to the request | |
if (!req.user) { | |
res.redirect('/login'); | |
return; | |
} | |
res.send(`Hello ${req.user.emails[0].address}`); | |
}); | |
app.get('/login', (req, res) => { | |
res.send(`<form action="/login" method="post"> | |
<div> | |
<label>Username:</label> | |
<input type="text" name="username"/> | |
</div> | |
<div> | |
<label>Password:</label> | |
<input type="password" name="password"/> | |
</div> | |
<div> | |
<input type="submit" value="Log In"/> | |
</div> | |
</form>`); | |
}); | |
app.post('/login', passport.authenticate('local', { | |
successRedirect: '/', | |
failureRedirect: '/error', | |
})); | |
// /api endpoint gets authentication via Basic Auth | |
// you auth by sending a base64 encoded username:password string via Authorization header | |
// see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization | |
app.use('/api', passport.authenticate('basic', { session: false })); | |
app.post('/api/ping', (req, res) => { | |
res.send(`pong ${req.user.emails[0].address}`); | |
}); | |
// eslint-disable-next-line | |
app.listen(port, async () => { | |
// eslint-disable-next-line | |
console.log(`API server running on ${port}!`); | |
await mongoose.connect(process.env.DATABASE_URL, { useNewUrlParser: true, useUnifiedTopology: true }); | |
// eslint-disable-next-line | |
console.log('Connected to the database'); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment