mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-02-22 18:42:23 +01:00
Add guide on session based authentication
This commit is contained in:
parent
430b78f8ae
commit
9727a3daae
@ -1,4 +1,14 @@
|
||||
[
|
||||
{
|
||||
"id": "session-based-authentication",
|
||||
"title": "Session Based Authentication",
|
||||
"description": "Learn what is Session Based Authentication and how to implement it in Node.js",
|
||||
"isNew": true,
|
||||
"type": "textual",
|
||||
"authorUsername": "kamranahmedse",
|
||||
"updatedAt": "2022-11-01T19:59:14.191Z",
|
||||
"createdAt": "2022-11-01T19:59:14.191Z"
|
||||
},
|
||||
{
|
||||
"id": "http-basic-authentication",
|
||||
"title": "HTTP Basic Authentication",
|
||||
@ -13,7 +23,7 @@
|
||||
"id": "basics-of-authentication",
|
||||
"title": "Basics of Authentication",
|
||||
"description": "Learn the basics of Authentication and Authorization",
|
||||
"isNew": true,
|
||||
"isNew": false,
|
||||
"type": "textual",
|
||||
"authorUsername": "kamranahmedse",
|
||||
"updatedAt": "2022-09-21T19:59:14.191Z",
|
||||
|
199
content/guides/session-based-authentication.md
Normal file
199
content/guides/session-based-authentication.md
Normal file
@ -0,0 +1,199 @@
|
||||
HTTP is the internet protocol that standardizes how clients and servers interact with each other. When you open a website, among other things, HTTP is the protocol that helps load the website in the browser.
|
||||
|
||||
## HTTP is Stateless
|
||||
HTTP is a stateless protocol which means that each request made from the client to the server is treated as a standalone request; neither the client nor the server keeps track of the subsequent requests. Sessions allow you to change that; with sessions, the server has a way to associate some information with the client so that when the same client requests the server, it can retrieve that information.
|
||||
|
||||
In this guide, we will learn what is Session-Based Authentication and how to implement it in Node.js. We also have a separate [visual guide on Session-Based Authentication](/guides/session-authentication) as well that explains the topic visually.
|
||||
|
||||
## What is Session-Based Authentication?
|
||||
Session-based authentication is a stateful authentication technique where we use sessions to keep track of the authenticated user. Here is how Session Based Authentication works:
|
||||
|
||||
* User submits the login request for authentication.
|
||||
* Server validates the credentials. If the credentials are valid, the server initiates a session and stores some information about the client. This information can be stored in memory, file system, or database. The server also generates a unique identifier that it can later use to retrieve this session information from the storage. Server sends this unique session identifier to the client.
|
||||
* Client saves the session id in a cookie and this cookie is sent to the server in each request made after the authentication.
|
||||
* Server, upon receiving a request, checks if the session id is present in the request and uses this session id to get information about the client.
|
||||
|
||||
And that is how session-based authentication works.
|
||||
|
||||
## Session-Based Authentication in Node.js
|
||||
Now that we know what session-based authentication is, let's see how we can implement session-based authentication in Node.js.
|
||||
|
||||
Please note that, for the sake of simplicity, I have intentionally kept the project strictly relevant to the Session Based Authentication and have left out a lot of details that a production-ready application may require. Also, if you don't want to follow along, project [codebase can be found on GitHub](https://github.com/kamranahmedse/node-session-auth-example).
|
||||
|
||||
First things first, create an empty directory that will be holding our application.
|
||||
|
||||
```shell
|
||||
mkdir session-auth-example
|
||||
```
|
||||
Now run the following command to setup a sample `package.json` file:
|
||||
```shell
|
||||
npm init -y
|
||||
```
|
||||
Next, we need to install the dependencies:
|
||||
```shell
|
||||
npm install express express-session
|
||||
```
|
||||
`Express` is the application framework, and `express-session` is the package that helps work with sessions easily.
|
||||
|
||||
### Setting up the server
|
||||
Now create an `index.js` file at the root of the project with the following content:
|
||||
|
||||
```javascript
|
||||
const express = require('express');
|
||||
const sessions = require('express-session');
|
||||
|
||||
const app = express();
|
||||
|
||||
app.use(sessions({
|
||||
secret: "some secret",
|
||||
cookie: {
|
||||
maxAge: 1000 * 60 * 60 * 24 // 24 hours
|
||||
},
|
||||
resave: true,
|
||||
saveUninitialized: false,
|
||||
}));
|
||||
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({extended: true}));
|
||||
|
||||
// @todo register routes
|
||||
|
||||
app.listen(3000, () => {
|
||||
console.log(`Server Running at port 3000`);
|
||||
});
|
||||
```
|
||||
The important piece to note here is the `express-session` middleware registration which automatically handles the session initialization, cooking parsing and session data retrieval, and so on. In our example here, we are passing the following configuration options:
|
||||
* `secret`: This is used to sign the session ID cookie. Using a secret that cannot be guessed will reduce the ability to hijack a session.
|
||||
* `cookie`: Object containing the configuration for session id cookie.
|
||||
* `resave`: Forces the session to be saved back to the session store, even if the session data was never modified during the request.
|
||||
* `saveUninitialized`: Forces an "uninitialized" session to be saved to the store, i.e., saves a session to the store even if the session was not initiated.
|
||||
|
||||
Another important option is `store` which we can configure to change how/where the session data is stored on the server. By default, this data is stored in the memory, i.e., `MemoryStore`.
|
||||
|
||||
Look at the [express-session documentation](https://github.com/expressjs/session) to learn more about the available options.
|
||||
|
||||
### Creating Handlers
|
||||
Create a directory called the `handlers` at the project's root. This is the directory where we will be placing all the route-handling functions.
|
||||
|
||||
Now let's create the homepage route, which will show the welcome message and a link to log out for the logged-in users and redirect to the login screen for the logged-out users. Create a file at `handlers/home.js` with the following content.
|
||||
|
||||
```javascript
|
||||
module.exports = function HomeHandler(req, res) {
|
||||
if (!req.session.userid) {
|
||||
return res.redirect('/login');
|
||||
}
|
||||
|
||||
res.setHeader('Content-Type', 'text/HTML)
|
||||
res.write(`
|
||||
<h1>Welcome back ${req.session.userid}</h1>
|
||||
<a href="/logout">Logout</a>
|
||||
`);
|
||||
|
||||
res.end()
|
||||
}
|
||||
```
|
||||
|
||||
At the top of this function, you will notice the check `req.session.userid`. `req.session` is automatically populated using the session cookie by the `express-session` middleware that we registered earlier. `req.session.userid` is one of the data fields that we will set to store the `userid` of the logged in user.
|
||||
|
||||
Next, we need to register this handler with a route. Open the `index.js` file at the root of the project and register the following route:
|
||||
|
||||
```javascript
|
||||
const HomeHandler = require('./handlers/home.js');
|
||||
|
||||
app.get('/', HomeHandler);
|
||||
```
|
||||
|
||||
Next, we have the login page, redirecting the user to the home screen if the user is logged in or showing the login form. Create a file at `handlers/login.js` with the following content:
|
||||
|
||||
```javascript
|
||||
module.exports = function LoginHandler(req, res) {
|
||||
if (req.session.userid) {
|
||||
return res.redirect('/');
|
||||
}
|
||||
|
||||
res.setHeader('Content-Type', 'text/HTML)
|
||||
res.write(`
|
||||
<h1>Login</h1>
|
||||
<form method="post" action="/process-login">
|
||||
<input type="text" name="username" placeholder="Username" /> <br>
|
||||
<input type="password" name="password" placeholder="Password" /> <br>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
`);
|
||||
|
||||
res.end();
|
||||
}
|
||||
```
|
||||
Again, at the top of the function, we are simply checking if we have `userid` in the session (which means the user is logged in). If the user is logged in, we redirect them to the homepage; if not, we show the login screen. In the login form, we have the method of `post`, and we submit the form to `/process-login`. Please note that, for the sake of simplicity, we have a simple HTML string returned in the response, but in a real-world application, you will probably have a separate view file.
|
||||
|
||||
Let's first register this page and then implement `/process-login` endpoint. Open the `index.js` file from the root of the project and register the following route:
|
||||
|
||||
```javascript
|
||||
const LoginHandler = require('./handlers/login.js');
|
||||
|
||||
app.get('/login', LoginHandler);
|
||||
```
|
||||
|
||||
Next, we have to implement the functionality to process the login form submissions. Create a file at `handlers/process-login.js` with the following content:
|
||||
|
||||
```javascript
|
||||
module.exports = function processLogin(req, res) {
|
||||
if (req.body.username !== 'admin' || req.body.password !== 'admin') {
|
||||
return res.send('Invalid username or password);
|
||||
}
|
||||
|
||||
req.session.userid = req.body.username;
|
||||
|
||||
res.redirect('/');
|
||||
}
|
||||
```
|
||||
|
||||
As you can see, we are simply checking that the username and password should both be `admin` and `admin` for a user to authenticate successfully. Upon finding valid credentials, we set the `userid` in the session by updating `req.session.userid`. Similarly, you can set any data in the session. For example, if we wanted to store the user role, we would do the following:
|
||||
|
||||
```javascript
|
||||
req.session.role = 'admin'
|
||||
```
|
||||
|
||||
And later access this value out of the session anywhere in the subsequent requests.
|
||||
|
||||
Register this route in the `index.js` file at the root of the project:
|
||||
|
||||
```javascript
|
||||
const ProcessLoginHandler = require('./handlers/process-login.js');
|
||||
|
||||
app.post('/process-login', ProcessLoginHandler);
|
||||
```
|
||||
|
||||
Finally, we have the logout functionality. Create a file at `handlers/logout.js` with the following content:
|
||||
|
||||
```javascript
|
||||
module.exports = function Logout(req, res) {
|
||||
req.session.destroy();
|
||||
res.redirect('/');
|
||||
}
|
||||
```
|
||||
|
||||
We reset the session by calling `req.session.destroy()` and then redirecting the user to the homepage. Register the logout handler in the `index.js` file using the following:
|
||||
|
||||
```javascript
|
||||
const LogoutHandler = require('./handlers/logout.js');
|
||||
|
||||
app.get('/logout', LogoutHandler);
|
||||
```
|
||||
|
||||
## Running the Application
|
||||
Open the `package.json` file and register the `start` script as follows:
|
||||
|
||||
```javascript
|
||||
"scripts": {
|
||||
"start": "node index.js"
|
||||
},
|
||||
```
|
||||
|
||||
Now you can start the application by running the following command:
|
||||
|
||||
```shell
|
||||
npm run start
|
||||
```
|
||||
|
||||
Now, if you open up your browser and visit the project at `http://localhost:3000` you will be able to see the Session-Based Authentication in action.
|
@ -25,7 +25,7 @@
|
||||
"id": "graph-data-structure",
|
||||
"title": "Graph Data Structure",
|
||||
"description": "Learn everything you need to know about the graph data structure",
|
||||
"isNew": true,
|
||||
"isNew": false,
|
||||
"youtubeLink": "https://www.youtube.com/watch?v=0sQE8zKhad0",
|
||||
"authorUsername": "kamranahmedse",
|
||||
"duration": "13 minutes",
|
||||
|
@ -117,7 +117,13 @@
|
||||
<url>
|
||||
<loc>https://roadmap.sh/flutter</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<lastmod>2022-10-29T13:00:53.994Z</lastmod>
|
||||
<lastmod>2022-10-31T06:17:18.118Z</lastmod>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://roadmap.sh/guides/session-based-authentication</loc>
|
||||
<changefreq>monthly</changefreq>
|
||||
<lastmod>2022-11-01T19:59:14.191Z</lastmod>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
|
Loading…
x
Reference in New Issue
Block a user