BootCamp by Dr.Angela
1. Introduction to Authentication
- Why Authenticate? : Authentication verifies a user's identity and restricts access to protected resources
- Typical authentication flow : Create Account → Log In → Access Protected Resources
- Common Authentication Methods : Email & Password, OAuth (Google, GitHub, Facebook, etc.)
2. Level 1 – Registering Users with Email and Password
- Basic authentication process : User registers with an email and password -> Credentials are stored securely in the database -> User logs in using the same credentials -> The server verifies the information before granting access
- Never store passwords as plain text.
3. Level 2 – Encryption vs Hashing
- Encryption
- Encryption converts readable data into ciphertext using a key Plaintext + Key ↓ Encryption ↓ Ciphertext
- Decryption restores the original data using the same (or a corresponding) key
- Caesar Cipher : https://cryptii.com/pipes/caesar-cipher/
- Hashing : Hashing converts data into a fixed-length value using a one-way hash function
Password
↓
Hash Function
↓
Hashed Password
- One-way transformation, Cannot be reversed, Used to store passwords securely
4. How Passwords Are Cracked
- Hash Tables : Attackers can compare stored hashes against precomputed hash tables (or rainbow tables) to guess passwords, To reduce this risk, modern applications use salting.
5. Level 3 – Salting Passwords with bcrypt
- What is Salting? : A random value (salt) is added before hashing
Password + Salt
↓
Hash Function
↓
Hashed Password
- Benefits : Prevents identical passwords from producing identical hashes, Makes rainbow table attacks impractical
- Salt Rounds : Higher salt rounds increase security, Higher values also require more processing time.
- bcrypt : https://www.npmjs.com/package/bcrypt
- Hash a password : import bcrypt from "bcrypt"; bcrypt.hash(password, saltRounds, (err, hash) => {});
- Compare passwords : bcrypt.compare(loginPassword, storedHash, (err, result) => {});
6. Managing Cookies and Sessions
- Sessions : A session stores user login information on the server, ex) import session from "express-session";
app.use(
session({
secret: "TOPSECRETWORD",
resave: false,
saveUninitialized: true,
})
);
- Passport.js : Passport is an authentication middleware for Express
- https://www.passportjs.org/
- Initialization : import passport from "passport";
app.use(passport.initialize());
app.use(passport.session());
- Middleware order matters.
- passport-local : Used for username/password authentication, ex) import { Strategy } from "passport-local";
passport.use(
new Strategy(async function verify(username, password, cb) {})
);
passport.serializeUser((user, cb) => {
cb(null, user);
});
passport.deserializeUser((user, cb) => {
cb(null, user);
});
7. Level 5 – Environment Variables
- Why Use Environment Variables? : Never store sensitive information inside your repository
- Examples : API Keys, Session Secrets, Database Passwords, OAuth Client Secrets
- dotenv : https://www.npmjs.com/package/dotenv
- ex) import env from "dotenv";
env.config();
- Using environment variables :
app.use(
session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: true,
})
);
- .gitignore : Common files to ignore
- Examples : .env, .DS_Store, .Trashes, *.exe, *.zip, API Keys, Secrets, Log files, ...
- https://github.com/github/gitignore/blob/main/Node.gitignore
8. Setting Up Google OAuth Credentials
- Google Cloud Console : https://console.cloud.google.com/
- Required credentials : Client ID, Client Secret
9. Level 6 – OAuth: Sign in with Google
- OAuth (Open Authorization) : OAuth allows users to log in without sharing their passwords with third-party applications
- Why OAuth? : Delegated authentication, Granular permission control, Read-only or read/write access, Users can revoke access at any time
- OAuth Flow : Set Up Application ↓ Redirect User to Google ↓ User Logs In ↓ User Grants Permission ↓ Authorization Code ↓ Access Token ↓ Access Protected Resources
- Authorization Code vs Access Token
- Authorization Code : One-time code used to obtain a token
- Access Token : Temporary credential used to access APIs
- Google OAuth : ex) import GoogleStrategy from "passport-google-oauth2";
app.get(
"/auth/google",
passport.authenticate("google", {
scope: ["profile", "email"],
})
);
app.get(
"/auth/google/secrets",
passport.authenticate("google", {
successRedirect: "/secrets",
failureRedirect: "/login",
})
);
- Configure the strategy : passport.use( "google", new GoogleStrategy( { clientID: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, callbackURL: "http://localhost:3000/auth/google/secrets", userProfileURL: "https://www.googleapis.com/oauth2/v3/userinfo", }, async (accessToken, refreshToken, profile, cb) => { // Find or create user } ) );
Top comments (0)