Skip to content
    SeaCode
    Learning tracksCode ArenaWorkshops & EventsInstructors
    Log inSign up
    NODENode.js

    Runtime and core tooling

    • What is Node.js?
    • CommonJS and ES modules
    • npm and package.json
    • process and command-line apps

    Async I/O and events

    • Event loop: callbacks to async/await
    • Files and paths with fs/promises
    • EventEmitter
    • Streams and backpressure

    HTTP and APIs

    • Your first HTTP server
    • Routing and JSON bodies
    • Build a tiny router and middleware chain
    • REST: resources and status codes
    • Validation and error handling

    Production: security, testing and deployment

    • Authentication basics with crypto
    • Configuration and environment secrets
    • Testing with assert and node:test
    • API security fundamentals
    • Project: tasks REST API and deployment
    Node.js

    Production: security, testing and deployment · Lesson 14 of 18

    Authentication basics with crypto

    Hash passwords correctly and understand signed tokens without inventing production auth.

    14 minutes2 games

    Passwords must never be stored as plaintext or with a fast hash such as SHA-256. Use a deliberately slow password KDF such as scrypt, Argon2 or bcrypt with a random salt per user. At login derive again and compare with timingSafeEqual. Then a session or token represents the authenticated identity.

    Password + random salt

    slow scrypt

    salt + derived hash

    timing-safe verify

    Node.js
    const crypto = require("node:crypto")
    const salt = Buffer.from("00112233445566778899aabbccddeeff", "hex") // fixed for this deterministic demo only
    const saved = crypto.scryptSync("correct horse", salt, 32)
    function verify(password) {
      const candidate = crypto.scryptSync(password, salt, 32)
      return crypto.timingSafeEqual(saved, candidate)
    }
    console.log(verify("correct horse"), verify("wrong"))

    An HMAC-signed token proves a payload was not changed, but it is not encrypted; anyone holding it can read it. Verify signature, expiry, issuer and audience, and pin the algorithm. In production use a reviewed auth or JWT library, or established sessions, rather than an educational mini implementation.

    Important

    The demo fixes its salt only for deterministic teaching. Applications must use randomBytes(16) per password and store the salt and parameters beside the hash. Rotate exposed secrets, require HTTPS, rate-limit login and offer MFA for sensitive accounts.

    Quick question

    Does a signed JWT hide its payload?

    Interview question

    How do hashing and encryption differ for passwords?

    Exercise

    Write sign(value, secret) using HMAC SHA-256 and valid to compare signatures. Print true false.

    Expected output: true false

    Node.js
    const crypto = require("node:crypto")
    function sign(value, secret) {
    
    }
    function valid(value, signature, secret) {
    
    }
    const token = sign("user:42", "demo-secret")
    console.log(valid("user:42", token, "demo-secret"), valid("user:7", token, "demo-secret"))

    Learn more from

    • Node.js: Cryptonodejs.org
    • OWASP: Password Storagecheatsheetseries.owasp.org

    Played 0 of 2 games

    Sign in to save your progress and earn XP.

    PreviousValidation and error handlingNextConfiguration and environment secrets
    SeaCode

    Learn to code for real, online or at our branch in front of Cairo University, Giza.

    Learn

    • All courses
    • Interactive tutorials
    • Interview practice problems
    • Mock interview
    • Learning tracks
    • Code Arena
    • Workshops & Events
    • Knowledge library
    • Team projects

    Your account

    • Log in
    • Sign up
    • Learning plan
    • Certificates
    • Site map

    Contact us

    • WhatsApp
    • 010 9094 1104
    • In front of Cairo University, Giza

    © 2026 SeaCode. All rights reserved.