MysticSnows / Secrets-Web

To learn and implement Authentication and Security for a website that stores secrets

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cookies

When user sends GET & POST then Cookies are

  1. Generated By Server
  2. Sent to Client Browser
  3. Saved on Client Browser

When user revisits the same site

  1. Cookies are sent to server along with the HTTP request
  2. Server sends some data as response back to client

Authentication

We can create a persistent session using cookies.
Required modules for this version of project:
npm install passport passport-local express-session bcrypt

Order of Operations in Codebase

const bcrypt = require('bcrypt')
const saltRounds = 10;
const session = require('express-session')
const passport = require('passport')
const LocalStrategy = require("passport-local").Strategy;

1. Initialize Session of express-session

app.use(session({
  secret: process.env.SECRET_KEY,
  resave: false,
  saveUninitialized: false
}));

2. Initialize passport for use (Comes from passport)

app.use(passport.initialize());

3. For persistent session (Comes from passport)

app.use(passport.session());

4. Configure passport local strategy

// traditional method. Requires LocalStrategy defined right after passport
passport.use(new LocalStrategy(User.authenticate()));
// new method defined by passport-local-mongoose
passport.use(User.createStrategy());

5. To serialize and deserialize cookies (Comes from passport-local)

passport.serializeUser((user, done) => {
	done(null, user.id);
});

passport.deserializeUser((id, done) => {
	User.findById(id)
		.then((founduser) => {
			done(null, founduser);
		})
		.catch(err => {
			done(err);
		});
});

Register

bcrypt.hash(req.body.password, saltRounds, (err, hash) => {
if (err) {
	console.log(err);
} else {
	const newUser = new User({
		username: req.body.username,
		password: hash
	})
	newUser.save()
		.then(() => {
			passport.authenticate('local', {
				successRedirect: '/secrets',
				failureRedirect: '/login'
			})(req, res);
		})
}
})

Login

const user = new User({
	username: req.body.useername,
	password: req.body.password
});
req.login(user, (err) => {
	if (err) {
		console.log(err);
	} else {
		passport.authenticate('local', {
			successRedirect: '/secrets'
		})(req, res);
	}
});

Validate a protected route

Reference: express-session

// To prevent back button redirect after log out
res.header('Cache-Control', 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0');

if (req.isAuthenticated()) {
	// Render Protected Endpoint
} else {
	res.redirect("/login");
}

Logout

Reference: passport
Alternative method is on: express-session

app.route('/logout')
	.get((req, res) => {
		req.logOut((err) => {
			if (err) {
				console.log(err);
			} else {
				res.redirect('/');
			}
		});
	});

Google OAuth2

OAuth npm install passport-google-oauth2
findOrCreate: npm install mongoose-findorcreate
Google OAuth Console
Then

const findOrCreate = require('mongoose-findorcreate');
// Define googleSchema
googleSchema.plugin(findOrCreate);

auth.js basic Structure

var GoogleStrategy = require( 'passport-google-oauth2' ).Strategy;

passport.use(new GoogleStrategy({
  clientID:     GOOGLE_CLIENT_ID,
  clientSecret: GOOGLE_CLIENT_SECRET,
  callbackURL: "http://yourdomain:3000/auth/google/callback",
  passReqToCallback   : true
  },
  function(request, accessToken, refreshToken, profile, done) {
    GoogleUser.findOrCreate({ googleId: profile.id }, function (err, user) {
      return done(err, user);
    });
  }
));

Then in app.js

// Google OAuth endpoint: Transfer request to Google for Google account login
app.get("/auth/google",
	passport.authenticate('google', {scope: ['email', 'profile']}));
// Google Callback endpoint: The one we defined in [google console > Credentials > 'OAuth 2.0 Client IDs']
app.get('/google/callback', 
	passport.authenticate('google', {
		successRedirect: '/secrets',
		failureRedirect: '/auth/failure'
	})
);
// Auth Failure Endpoint
app.get('/auth/failure', (req, res) => {
	res.send('Something Went Wrong...');
});

References

  1. passport
  2. passport-local
  3. express-session
  4. GFG Reference
  5. Medium Article
  6. Udemy Solution QNA
  7. Passport Google OAuth
  8. mongoose-findorcreate

About

To learn and implement Authentication and Security for a website that stores secrets


Languages

Language:JavaScript 57.0%Language:EJS 40.6%Language:CSS 2.4%