Dev.to Security ๐Ÿ” Cybersecurity ๐Ÿ‘ 0 ๐Ÿ“– 3 min read

Understanding Authentication Concepts

What is Axios? Explanation JWT & Bcrypt JWT is a way to securely transmit information between parties as a JSON object. Think of it as a digital passport: Structure: header.payload.signature Use: After login, the ser

What is Axios?

Explanation JWT & Bcrypt
JWT is a way to securely transmit information between parties as a JSON object. Think of it as a digital passport:

  • Structure: header.payload.signature
  • Use: After login, the server gives you a token. You send this token with every request to prove "you are you"

Bcrypt is a password hashing algorithm:

  • Hashing = Turning a password into a scrambled, irreversible string
  • Salt = Adds random data to make each hash unique
  • Slow = Deliberately slow to prevent brute force attacks

The Authentication Flow:

  1. User signs up โ†’ Password โ†’ Bcrypt hashes โ†’ Save in database
  2. User logs in โ†’ Check password with Bcrypt โ†’ If correct, create JWT
  3. User sends JWT with requests โ†’ Server verifies JWT โ†’ Allow access

How to Install
Run this command in your terminal:
shell
npm install jsonwebtoken bcryptjs
npm install --save-dev @types/jsonwebtoken @types/bcryptjs

Setting Up Environment Variables
Create .env.local:

JWT_SECRET=your-super-secret-key-change-this-in-production
JWT_EXPIRES_IN=7d

Bcrypt - Password Hashing

Create a folder app/api/auth/register/route.ts import:

import { NextResponse } from 'next/server';
import bcrypt from 'bcryptjs';

And Then:

export async function POST(request: Request) {
  try {
    // 1. Get data from request
    const { email, password, name } = await request.json();
    // 2. Validate (simple check)
    if (!email || !password) {
      return NextResponse.json(
        { error: 'Email and password required' },
        { status: 400 }
      );
    }
    // 3. Hash the password with bcrypt
    const saltRounds = 10; // Higher = more secure, but slower
    const hashedPassword = await bcrypt.hash(password, saltRounds);
    // 4. Save user to database (we'll use mock data for now)
    // In real project: Save to MongoDB/PostgreSQL
    const mockUser = {
      id: Date.now(),
      email,
      name,
      password: hashedPassword, // Save HASHED password, NOT plain text!
    };
    // 5. Return success response
    return NextResponse.json(
      { 
        message: 'User created successfully',
        user: { id: mockUser.id, email, name }
      },
      { status: 201 }
    );
  } catch (error) {
    return NextResponse.json(
      { error: 'Something went wrong' },
      { status: 500 }
    );
  }
}

Password Hashing Explained

Hash the password:

const hashedPassword = await bcrypt.hash(plainPassword, 10);

Result:

$2a$10$UY8x9sKjdlKjfaksjdf98234kjsdf"

Why?

  • Even if database is hacked, hackers can't read the password!

JWT - Creating and Verifying Tokens

Create app/api/auth/login/route.ts:
Import:

import { NextResponse } from 'next/server';
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';

Mock database (in real project,we use real DB):

const users = [
  {
    id: 1,
    email: '[email protected]',
    password: '$2a$10$...', // Hashed password from registration
    name: 'Test User'
  }
];

And then, Create an async function:

export async function POST(request: Request) {
  try {
    const { email, password } = await request.json();
    // 1. Find user in database
    const user = users.find(u => u.email === email);
    if (!user) {
      return NextResponse.json(
        { error: 'Invalid credentials' },
        { status: 401 }
      );
    }
    // 2. Check password with bcrypt
    const isValid = await bcrypt.compare(password, user.password);
    if (!isValid) {
      return NextResponse.json(
        { error: 'Invalid credentials' },
        { status: 401 }
      );
    }
    // 3. Create JWT token
    const token = jwt.sign(
      { 
        userId: user.id, 
        email: user.email 
      },
      process.env.JWT_SECRET!, // Your secret key
      { expiresIn: '7d' }      // Token expires in 7 days
    );
    // 4. Return token to client
    return NextResponse.json({
      token,
      user: {
        id: user.id,
        email: user.email,
        name: user.name
      }
    });
  } catch (error) {
    return NextResponse.json(
      { error: 'Login failed' },
      { status: 500 }
    );
  }
}

Verifying JWT Token in Protected Routes

Create app/api/auth/profile/route.ts:
Import:

import { NextResponse } from 'next/server';
import jwt from 'jsonwebtoken';

Create a GET Request:

export async function GET(request: Request) {
  try {
    // 1. Get token from Authorization header
    const authHeader = request.headers.get('authorization');
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      return NextResponse.json(
        { error: 'No token provided' },
        { status: 401 }
      );
    }
    // 2. Extract token (remove "Bearer " prefix)
    const token = authHeader.split(' ')[1];
    // 3. Verify and decode token
    const decoded = jwt.verify(token, process.env.JWT_SECRET!);
    // 4. Return user data
    return NextResponse.json({
      user: decoded,
      message: 'Protected data accessed!'
    });
  } catch (error) {
    return NextResponse.json(
      { error: 'Invalid or expired token' },
      { status: 401 }
    );
  }
}```



**Using Authentication**
In Login Form Component:

``
 try {
      const response = await fetch('/api/auth/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email, password }),
      });
      const data = await response.json();
      if (!response.ok) {
        throw new Error(data.error || 'Login failed');
      }
``

**Save token to cookies:**
``
Cookies.setItem('token', data.token);
Cookies.setItem('user', JSON.stringify(data.user));
``

Or we can create a utility function in lib/auth.ts instead of writing here.

๐Ÿ“ฐ Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes โ€” full credit and traffic to the original publisher.