0% found this document useful (0 votes)
4 views

Auth

The document provides an overview of authentication processes, focusing on methods such as JWT, cookies, and local storage. It explains the role of cookies in session management, personalization, tracking, and security, including attributes like SameSite and HttpOnly to mitigate CSRF attacks. Additionally, it includes code examples for implementing authentication in both Express and React applications.

Uploaded by

loopspell1
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Auth

The document provides an overview of authentication processes, focusing on methods such as JWT, cookies, and local storage. It explains the role of cookies in session management, personalization, tracking, and security, including attributes like SameSite and HttpOnly to mitigate CSRF attacks. Additionally, it includes code examples for implementing authentication in both Express and React applications.

Uploaded by

loopspell1
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

7/8/24, 11:32 PM DailyCode

What is authentication?
Authentication is the process of letting users signup/signin into websites via username /
password or using SSO (single sign on)

https://projects.100xdevs.com/pdf/Auth/auth-1 1/13
7/8/24, 11:32 PM DailyCode

Authentication using jwt +


localstorage
Signup

Signin

Auth requests

https://projects.100xdevs.com/pdf/Auth/auth-1 2/13
7/8/24, 11:32 PM DailyCode

Authentication using cookies (Part 1)

What are cookies


Cookies in web development are small pieces of data sent from a website and stored on the
user's computer by the user's web browser while the user is browsing. They are designed to be a
reliable mechanism for websites to remember things (very similar to local storage)

1. Session Management: Cookies allow websites to identify users and track their individual
session states across multiple pages or visits.

2. Personalization: Websites use cookies to personalize content and ads. For instance, cookies
might store information about a user's preferences, allowing the site to tailor content or
advertisements to those interests.

3. Tracking: Cookies can track users across websites, providing insights into browsing behavior.
This information can be used for analytics purposes, to improve website functionality, or for
advertising targeting.

4. Security: Secure cookies can be used to enhance the security of a website by ensuring that
the transmission of information is only done over an encrypted connection, helping to
prevent unauthorized access to user data.

We will be focussing on point 4

Why not local storage?


Cookies and LocalStorage both provide ways to store data on the client-side, but they serve
different purposes and have different characteristics.

1. Cookies are send with every request to the website (by the browser) (you don’t have to
explicitly add a header to the fetch call)
This point becomes super important in Next.js, we’ll see later why

💡 Ref - https://github.com/100xdevs-cohort-2/paytm/blob/complete-
solution/frontend/src/pages/SendMoney.jsx#L45

https://projects.100xdevs.com/pdf/Auth/auth-1 3/13
7/8/24, 11:32 PM DailyCode

1. Cookies can have an expiry attached to them

2. Cookies can be be restricted to only https and to certain domains

Authentication with cookies (Part 2)

Signup

Signin

https://projects.100xdevs.com/pdf/Auth/auth-1 4/13
7/8/24, 11:32 PM DailyCode

Auth endpoints

You don’t need to explicitly set the cookie header in the browser. It’s automatically set by the
browser in every request

Properties of cookies
Types of cookies
1. Persistent - Stay even if u close the window

2. Session - Go away after the window closes

3. Secure - Sent only over secure, encrypted connections (HTTPS).

Properties of cookies
HttpOnly - Can not be accessed by client side scripts

SameSite - Ensures cookies are not send on cross origin requests

1. Strict

2. Lax - Only GET requests and on top level navigation

3. None

Ref - https://portswigger.net/web-security/csrf/bypassing-samesite-
restrictions#:~:text=SameSite is a browser security,leaks%2C and some CORS exploits.

https://projects.100xdevs.com/pdf/Auth/auth-1 5/13
7/8/24, 11:32 PM DailyCode

Domains - You can also specify what all domains should the cookie be sent from

CSRF attacks
Cross site request forgery attacks were super common because of cookies and hence the
SameSite attribute was introduced

Let’s see a few cases

SameSite: none

SameSite: Strict

https://projects.100xdevs.com/pdf/Auth/auth-1 6/13
7/8/24, 11:32 PM DailyCode

But there’s a problem -

SameSite: Lax

https://projects.100xdevs.com/pdf/Auth/auth-1 7/13
7/8/24, 11:32 PM DailyCode

Example in express (Backend)


1. Initialize an empty TS project

npm init -y Copy


npx tsc --init

1. Update rootDir and outDir

"roodDir": "./src" Copy


"outDir": "./dist"

1. Add required libraries

import express from "express"; Copy


import cookieParser from "cookie-parser";
import cors from "cors";
import jwt, { JwtPayload } from "jsonwebtoken";
import path from "path";

1. Initialize express app, add middlewares

const app = express(); Copy


app.use(cookieParser());
app.use(express.json());
app.use(cors({
credentials: true,
origin: "http://localhost:5173"
}));

1. Add a dummy signin endpoint

app.post("/signin", (req, res) => { Copy


const email = req.body.email;
const password = req.body.password;
https://projects.100xdevs.com/pdf/Auth/auth-1 8/13
7/8/24, 11:32 PM DailyCode

// do db validations, fetch id of user from db


const token = jwt.sign({
id: 1
}, JWT_SECRET);
res.cookie("token", token);
res.send("Logged in!");
});

1. Add a protected backend route

app.get("/user", (req, res) => { Copy


const token = req.cookies.token;
const decoded = jwt.verify(token, JWT_SECRET) as JwtPayload;
// Get email of the user from the database
res.send({
userId: decoded.id
})
});

1. Add a logout route

Copy
app.post("/logout", (req, res) => {
res.cookie("token", "ads");
res.json({
message: "Logged out!"
})
});

1. Listen on port 3000

Copy
app.listen(3000);

Code - https://github.com/100xdevs-cohort-2/week-16-auth-1

Frontend in React
Initialize an empty react project

https://projects.100xdevs.com/pdf/Auth/auth-1 9/13
7/8/24, 11:32 PM DailyCode

Add a signin page

import { useState } from "react" Copy


import { BACKEND_URL } from "../config"
import axios from "axios"

export const Signin = () => {


const [username, setUsername] = useState("")
const [password, setPassword] = useState("")

return <div>
<input onChange={(e) => {
setUsername(e.target.value);
}} type="text" placeholder="username" />
<input onChange={(e) => {
setPassword(e.target.value);
}} type="password" placeholder="password" />
<button onClick={async () => {
await axios.post(`${BACKEND_URL}/signin`, {
username,
password
}, {
withCredentials: true,
});
alert("you are logged in")
}}>Submit</button>
</div>
}

Add a user page

import axios from "axios"; Copy


import { useEffect, useState } from "react"
import { BACKEND_URL } from "../config";

export const User = () => {


const [userData, setUserData] = useState();

useEffect(() => {
axios.get(`${BACKEND_URL}/user`, {
withCredentials: true,
})
.then(res => {
setUserData(res.data);
})
}, []);

return <div>
You're id is {userData?.userId}
<br /><br />
<button onClick={() => {
https://projects.100xdevs.com/pdf/Auth/auth-1 10/13
7/8/24, 11:32 PM DailyCode

axios.post(`${BACKEND_URL}/logout`, {}, {
withCredentials: true,
})
}}>Logout</button>
</div>
}

Add routing

import './App.css' Copy

import { BrowserRouter, Route, Routes } from "react-router-dom";


import { Signup } from './components/Signup';
import { Signin } from './components/Signin';
import { User } from './components/User';

function App() {
return (
<BrowserRouter>
<Routes>
<Route path={"/signup"} element={<Signup />} />
<Route path={"/signin"} element={<Signin />} />
<Route path={"/user"} element={<User />} />
</Routes>
</BrowserRouter>
)
}

export default App

Code - https://github.com/100xdevs-cohort-2/week-16-auth-1

Frontend from express


1. Add an index.html file in src folder of backend

<!DOCTYPE html> Co
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login Page</title>

https://projects.100xdevs.com/pdf/Auth/auth-1 11/13
7/8/24, 11:32 PM DailyCode

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>

<input id="username" type="text" placeholder="username" />


<input id="password" type="password" placeholder="password" />
<button id="loginButton">Submit</button>
<button id="logoutButton">Logout</button>
<div id="userData"></div>

<script>

document.getElementById('loginButton').addEventListener('click', async () => {


const username = document.getElementById('username').value;
const password = document.getElementById('password').value;

try {
await axios.post(`/signin`, {
username,
password
});
alert("You are logged in");
} catch (error) {
console.error('Login failed:', error);
alert("Login failed");
}
});

document.getElementById('logoutButton').addEventListener('click', () => {
axios.post(`/logout`, {}, {
withCredentials: true,
}).then(() => {
console.log('Logged out successfully.');
}).catch(error => {
console.error('Logout failed:', error);
});
});

function fetchUserData() {
axios.get(`/user`, {
withCredentials: true,
}).then(response => {
const userData = response.data;
displayUserData(userData);
}).catch(error => {
console.error('Failed to fetch user data:', error);
});
}

function displayUserData(userData) {
const userDataDiv = document.getElementById('userData');

https://projects.100xdevs.com/pdf/Auth/auth-1 12/13
7/8/24, 11:32 PM DailyCode

// Example: Assumes userData contains a 'name' and 'email'. Adapt based on yo


userDataDiv.innerHTML = `<p>Your id is: ${userData.userId}</p>`;
}
fetchUserData();
</script>

</body>
</html>

1. Add a route that sends this html file

app.get("/", (req, res) => { Copy


res.sendFile(path.join(__dirname, "../src/index.html"))
})

1. Remove credentials from cors

app.use(cors()); Copy

Link - https://github.com/100xdevs-cohort-2/week-16-auth-1

https://projects.100xdevs.com/pdf/Auth/auth-1 13/13

You might also like