Full Trust European Hosting

BLOG about Full Trust Hosting and Its Technology - Dedicated to European Windows Hosting Customer

Node.js Hosting Europe - HostForLIFE.eu :: When and How to Use Session vs. Token-Based Authentication in MERN?

clock July 30, 2025 07:37 by author Peter

The cornerstone of online application security is authentication. The authentication environment in MERN (MongoDB, Express.js, React, and Node.js) stack apps is dominated by two popular methods: two methods of authentication: session-based and token-based. Although they both accomplish the same objective—verifying a user's identity and safeguarding resources their implementation, application cases, and scalability are very different. This page describes each approach, how it functions in a MERN setting, and why it is better to use one over the other.

What is Authentication?
Before we dive in, let’s clarify.

  • Authentication: confirming the identity of the user (Are you who you say you are?)
  • Authorization: controlling access to resources (What can you do now that you're authenticated?)

Overview of Authentication Methods

Method Session-Based Authentication Token-Based Authentication
Storage Server-side (in memory or DB) Client-side (usually in localStorage or cookies)
Identity Proof Session ID (stored in cookie) JWT (JSON Web Token)
Stateless/Stateful Stateful Stateless
Scalability Less scalable unless using session store More scalable
Common Use Cases Traditional web apps SPAs, mobile apps, microservices

Session-Based Authentication (Cookie-Based)

How does it work?

  • User submits credentials via lthe ogin form.
  • Backend verifies and creates a session, saving it on the server (in memory, Redis, or DB).
  • Server returns a session ID in a secure HTTP-only cookie.
  • On each request, the browser sends the session ID via cookie.
  • Server looks up session data using the ID and verifies the user.

Where does it fit in MERN?

  • React: The frontend sends login requests and automatically includes cookies on future requests (if configured correctly).
  • Express/Node.js: Stores sessions using express-session or similar libraries.
  • MongoDB: Often used with a session store like connect-mongo.

Security Features

  • HttpOnly cookies protect against XSS.
  • Cookies can be set to SameSite, Secure, and have expiry times.

Drawbacks

  • Needs server-side storage (memory or DB).
  • Less ideal for horizontal scaling unless using a centralized session store (e.g., Redis).
  • Slightly more complex to manage in APIs for SPAs or mobile apps.

Token-Based Authentication (JWT)
How does it work?

  • User logs in with credentials.
  • Server verifies and returns a signed token (usually JWT).
  • Token is stored on the client (localStorage, sessionStorage, or cookie).
  • On each request, a token is sent in headers (commonly in Authorization: Bearer <token>).
  • Server validates token signature and grants access.

Where does it fit in MERN?

  • React: Stores token in localStorage or cookies, attaches it to API requests using Axios or Fetch.
  • Express/Node.js: Verifies token with jsonwebtoken or similar libraries.
  • MongoDB: Optionally stores refresh tokens for session control.

Security Features

  • Tokens can be signed with a secret or private key.
  • Supports token expiration (exp), issued at (iat), and more.

Drawbacks

  • If stored in localStorage, vulnerable to XSS attacks.
  • No built-in logout mechanism (tokens are self-contained).
  • Revocation is difficult without additional mechanisms (blacklists, short expiration with refresh tokens).

Comparison Table

Feature Session-Based Token-Based (JWT)
Storage Server-side (in-memory, Redis, DB) Client-side (localStorage, cookie)
Stateless No (unless using JWT in session) Yes
Suitable for SPAs With extra setup Best choice
Mobile Compatibility Harder (no cookie support) Very good
CSRF Protection (if using cookies) Requires manual implementation
XSS Risk Safer (HttpOnly cookies) Risky if using localStorage
Logout Server clears the session Token must expire or be blacklisted
Performance Lookup needed on each request No DB lookup if using stateless JWTs
Token Revocation Easy (delete session) Complex (blacklist, refresh tokens)

When to Use What?

Use Session-Based Authentication When

  • You’re building a server-rendered web app (e.g., admin dashboard).
  • You control both client and server and want automatic cookie handling.
  • You need simple session invalidation (e.g., logging users out remotely).
  • You can scale horizontally with a session store like Redis.

Use Token-Based Authentication (JWT) When?

  • You’re building a single-page application (SPA) with React.
  • You want to support mobile apps or third-party clients.
  • You prefer a stateless API that’s easy to scale.
  • You want users to remain authenticated across multiple domains/services (microservices).

Session + Token Hybrid Approach (Best of Both Worlds)
Many modern apps use a hybrid approach.

  • Store the JWT in an HttpOnly cookie (safer from XSS).
  • Use refresh tokens with short-lived access tokens.
  • Server can keep track of refresh tokens to allow logout.

This combines the statelessness of tokens with the security of sessions.

Final Thoughts

There’s no one-size-fits-all approach to authentication in the MERN stack. Your decision depends on.

  • Application type (SPA, mobile, or SSR).
  • Security requirements.
  • Scalability and infrastructure.
  • Developer experience and ease of maintenance.

Both session-based and token-based auth systems have matured. The best strategy in 2025 is to choose consciously based on your application’s architecture and implement it securely.

Conclusion
In the evolving world of full-stack development, especially in MERN applications, choosing the right authentication method is crucial for performance, security, and user experience. Session-based authentication remains reliable for traditional web apps where server-side session control is preferred. On the other hand, token-based authentication (JWT) is ideal for modern, stateless, API-driven applications like SPAs and mobile apps.

By understanding the trade-offs between these two approaches, developers can design authentication systems that are secure, scalable, and user-friendly. In many real-world scenarios, a hybrid approach combining short-lived tokens with secure cookies offers the best balance between security and flexibility.

Ultimately, the best choice is not about which method is superior - it's about which method aligns with your architecture, user experience goals, and scalability needs.

 



AngularJS Hosting Europe - HostForLIFE :: Angular Reactive Forms: Real-Time Problem Solving and Dynamic Validation

clock July 24, 2025 08:53 by author Peter

The handling of dynamic form validation in Angular Reactive Forms is described in this article. It illustrates a real-world situation in which validation rules must alter in response to user input, such as requiring a company name for corporations and a PAN number for individuals. According to the article, developers frequently make the error of forgetting to call updateValueAndValidity() after updating or clearing validators, which results in unexpected form behavior. It explains the problem, displays the code that was wrong and fixed, and offers a reusable custom validator for PAN format.


 Overall, with a useful example and real-time bug fixes, this article assists developers in understanding how to implement clear, dynamic validation logic in Angular forms.

Overview
Angular’s Reactive Forms module gives you fine-grained control over form data, structure, and validation. One of the most useful features is dynamically applying validators based on user input or context.

In real-world applications, dynamic validation is essential, for example, requiring a secondary email only if a checkbox is selected, or validating a PAN number only for Indian users.

Scenario

In one of our insurance applications, we had a registration form with the following fields:

  • User Type (Individual / Organization)
  • PAN Number (Mandatory for Individuals)
  • Company Name (Mandatory for Organizations)

The validation was supposed to change dynamically when the user toggles between "Individual" and "Organization".

Initial Implementation
Here’s the basic structure of the Reactive Form:
this.registrationForm = this.fb.group({
  userType: ['Individual'],
  panNumber: [''],
  companyName: ['']
});


In the onUserTypeChange() method, we tried to manually add/remove validators:
onUserTypeChange(userType: string) {
  if (userType === 'Individual') {
    this.registrationForm.get('panNumber')?.setValidators([
      Validators.required,
      this.panValidator
    ]);
    this.registrationForm.get('companyName')?.clearValidators();
  } else {
    this.registrationForm.get('companyName')?.setValidators([
      Validators.required
    ]);
    this.registrationForm.get('panNumber')?.clearValidators();
  }

  // Missing updateValueAndValidity
}

Real-Time Issue Faced
Despite switching user type, the form still showed both fields as invalid/valid incorrectly.

Root Cause
We forgot to call updateValueAndValidity() after changing the validators. As a result, the validation state wasn’t recalculated.

Fix Implemented
We modified the method to:
onUserTypeChange(userType: string) {
  const panControl = this.registrationForm.get('panNumber');
  const companyControl = this.registrationForm.get('companyName');

  if (userType === 'Individual') {
    panControl?.setValidators([Validators.required, this.panValidator]);
    companyControl?.clearValidators();
  } else {
    companyControl?.setValidators([Validators.required]);
    panControl?.clearValidators();
  }

  panControl?.updateValueAndValidity();
  companyControl?.updateValueAndValidity();
}


Also, we triggered onUserTypeChange() on form initialization to ensure it reflects the default selection.

Real-Time PAN Validator

Here’s how the PAN format validator looked:
panValidator(control: AbstractControl): ValidationErrors | null {
  const panRegex = /^[A-Z]{5}[0-9]{4}[A-Z]{1}$/;

  if (control.value && !panRegex.test(control.value)) {
    return { invalidPAN: true };
  }

  return null;
}

Outcome
The dynamic validation works perfectly now

Fields show real-time validation updates
This pattern is reusable across other forms with dynamic sections

Conclusion

Dynamic form validation is a common need in Angular apps. Always remember:

  • Use setValidators() and clearValidators() as needed
  • Call updateValueAndValidity() after updating validators
  • For complex logic, extract reusable custom validators

This simple oversight (not updating the validity) caused hours of confusion in a production bug. But the lesson helped in building better reactive forms in other modules too.



Visual Studio Hosting - HostForLIFE.eu :: Code cleanup in Visual Studio 2022

clock July 21, 2025 07:49 by author Peter

The Code Cleanup function in Visual Studio 2022 automatically formats and applies code style guidelines to your code. This keeps your codebase readable, maintainable, and clean.

What is Code Cleanup?
Code Cleanup applies refactoring and formatting rules to your code files. It includes:

  • Removing unnecessary usings/Imports
  • Sorting usings/Imports
  • Applying naming conventions
  • Formatting spacing and indentation
  • Converting var to explicit types (or vice versa)
  • Removing unused variables

How to Use Code Cleanup?
1. Using the Toolbar Button

  • Open a C#, VB.NET, or other supported code file.
  • Click the broom icon 🧹 on the bottom-right corner of the editor.
  • There may be two profiles (Profile 1, Profile 2). Click the dropdown arrow to choose or configure a profile.
  • Click the broom icon to run the cleanup.

2. Using a Keyboard Shortcut
Default shortcut: Ctrl + K, Ctrl + E
(You can customize it in Tools > Options > Keyboard).

3. Context Menu
Right-click anywhere in your code editor.
Select Run Code Cleanup

code clean up

Configure Code Cleanup Profiles
Go to: Tools > Options > Text Editor > [Your Language, e.g., C#] > Code Style > Code Cleanup
There are two profiles (Profile 1 & Profile 2). Each can be customized with:

  • Format document
  • Sort and remove usings
  • Apply file header
  • Apply naming rules
  • Remove unnecessary code

Click Configure Code Cleanup to choose what each profile should do.


Run Cleanup on Entire Solution or Project

  • Right-click on the Solution or Project in Solution Explorer.
  • Choose Analyze and Code Cleanup > Run Code Cleanup.

Note: By default, this only formats open documents. To apply it to all files, use a tool like Roslyn analyzers or the dotnet format CLI (for .NET Core/.NET 5+ projects).

Optional Tools for Deeper Cleanup

.editorconfig file: Store consistent code style settings in the repo.
Roslyn Analyzers: Enforce rules across the solution.
Refactoring Suggestions: Lightbulb actions (Ctrl + .)

Conclusion
In this article, I have tried to cover Code cleanup in Visual Studio 2022.



AngularJS Hosting Europe - HostForLIFE :: Communication Between Parent and Child Components: Resolving the Sync Problem

clock July 16, 2025 08:41 by author Peter

Component communication is essential for creating reusable and modular components in Angular. Data is often sent from a parent component to a child component using @Input() and returned using @Output() with an EventEmitter.

The Real Issue
One of our projects involved a parent component passing a selected item ID to a child component via @Input().  The child component used that ID to retrieve and show the details.  However, when the user quickly picked a different item, the kid did not always display the change.  Sometimes it displayed outdated info or didn't update at all.

What Went Wrong
Angular's @Input() only updates when the value changes, but in certain situations (such as when the same ID is passed again after a brief delay), lifecycle hooks like ngOnChanges() failed to detect it. Additionally, ngOnInit() wasn't retriggered on each input change because the child only made one HTTP call.

Solution


We moved the API fetch logic from ngOnInit() to ngOnChanges() and added a proper check for changes:
@Input() itemId!: string;

ngOnChanges(changes: SimpleChanges): void {
  if (changes['itemId'] && changes['itemId'].currentValue) {
    this.loadItemDetails(changes['itemId'].currentValue);
  }
}

loadItemDetails(id: string) {
  this.http.get(`/api/items/${id}`).subscribe(res => {
    this.itemDetails = res;
  });
}


We also added a condition to prevent redundant API calls if the ID hasn’t changed.

Additional Fix
For cases where the same value might be passed again, we manually reset the input before reassigning:
this.selectedItemId = null;
setTimeout(() => this.selectedItemId = item.id, 0);


This trick forces Angular to treat the new input as a different value.

Conclusion
Angular’s @Input() and @Output() work well for component communication, but they don’t always detect subtle changes unless lifecycle hooks are handled properly. Moving logic to ngOnChanges() ensures that child components respond to dynamic data accurately.



Node.js Hosting Europe - HostForLIFE.eu :: What is the architecture of Node.js?

clock July 14, 2025 08:04 by author Peter

It's likely that Node.js is responsible for any websites that load really quickly or change in real time, such as chat apps or live scores. However, what is Node.js and how does its architecture contribute to its power? Let's put it in plain language.

What is Node.js?
Node.js is not a programming language or a framework; it’s a runtime environment. It enables developers to run JavaScript on the server side, outside of the browser. It’s built on Google Chrome’s V8 JavaScript engine, which makes it super fast.

e.g: "Hello World" in Node.js.
// Import the built-in 'http' module
const http = require('http');

// Create a simple server
const server = http.createServer((req, res) => {
  res.end('Hello World from Node.js!');
});

// Server listens on port 3000
server.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});

This simple server handles HTTP requests using a single thread and responds with "Hello World". Even if 100 users open it at once, Node.js can manage that efficiently, thanks to its architecture.

Let’s break it down.

1. Single-Threaded Event Loop

Node.js uses a single thread to handle all client requests. That means it doesn’t create a new thread for every request like traditional web servers (such as Apache). Here the question comes.

Then, how does it handle multiple users simultaneously?

It supports multiple users simultaneously through its Event-Driven Architecture. Let's explore it.

2. Event-Driven Architecture

Imagine you are at a restaurant. Instead of the chef cooking only one dish at a time (waiting for it to finish before starting the next), he puts dishes in the oven and moves on to the next task. When the oven beeps, he knows the food is ready.

Our Node.js works in the same way.

  • When a request (like fetching data or reading a file) comes in, it’s added to the event queue.
  • Node.js doesn’t wait for the task to finish. Instead, it moves on to the next task.
  • Once the task is completed, Node.js receives notification (via a callback function) and processes the result.

This makes Node.js extremely fast and efficient, particularly for I/O-Intensive tasks.

  • Reading/writing files
  • Talking to databases
  • Calling APIs

3. Non-Blocking I/O

  • Most web servers use blocking I/O, which means they wait for one operation to finish before moving to the next.
  • Node.js uses non-blocking I/O, meaning it doesn’t wait for input. This allows Node.js to handle thousands of requests per second with a single thread.

Let's simulate a non-blocking operation, such as reading a file.
const fs = require('fs');

console.log('Start reading file...');

fs.readFile('example.txt', 'utf8', (err, data) => {
  if (err) {
    return console.error(err);
  }
  console.log('File content:', data);
});

console.log('Reading file initiated...');


Output

Key Components of Node.js Architecture
Here are the main parts that makeup Node.

Components Role

V8 Engine

Converts JavaScript code into machine code. It’s fast and powerful.

Libuv

A library that provides the event loop and handles asynchronous operations.

Event Loop

Keeps checking for completed tasks and runs their callback functions.

CallBacks

Functions that are executed when a task finishes.

APIs

Node.js provides APIs for file systems, networks, and more.

Advantages of Node.js Architecture
Fast: Thanks to V8 and the non-blocking model.

  • Scalable: Handles a large number of users without crashing or slowing down.
  • Efficient: Great for real-time apps like chat, games, or live data.
  • Lightweight: Uses fewer system resources compared to traditional servers.

When to Use Node.js?
Node.js is ideal for.

  • Real-time apps (chat apps, online games)
  • APIs for web/mobile apps
  • Data streaming apps
  • Single Page Applications (SPAs)

Conclusion
Node.js architecture is what makes it stand out. Its event-driven, non-blocking, and single-threaded design helps developers build fast, scalable, and efficient applications.

HostForLIFE.eu Node.js Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



AngularJS Hosting Europe - HostForLIFE :: Lazy Loading in Angular: An Issue and Fix in Real Time

clock July 10, 2025 07:49 by author Peter

A common technique for improving performance in large Angular apps is lazy loading. The practice of loading a module only after the user has reached its route is known as lazy loading. This reduces the initial load time of the application. In one of our projects, we had a dashboard module that was loaded slowly. The module worked flawlessly when the app was being used. However, when the user reloaded the browser while on the dashboard route (http://localhost:4200/dashboard), a blank page or 404 error was shown.

Causes of the Issue
Client-side angular routing is used. When you hit refresh, the browser asks the server to fetch that route, but the server is not aware of this.

How Did We Fix It?
We fixed that by instructing the server to divert all requests to index.html so that Angular could handle the routing. In this case, we changed the.htaccess file with the following since we were using an Apache server:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /

  RewriteRule ^index\.html$ - [L]

  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d

  RewriteRule . /index.html [L]

</IfModule>


There is no issue if you use the built-in dev server in Angular CLI, as it takes care of this already. However, the hosting server needs to know for production.

Conclusion

App performance is enhanced by lazy loading, but if the server is not set up correctly, it may result in unforeseen problems. To allow Angular to handle routing, always ensure that your server reroutes unknown routes to index.html.



AngularJS Hosting Europe - HostForLIFE :: Angular Lifecycle Hooks: An Understanding

clock July 1, 2025 08:06 by author Peter

Google developed the open-source Angular frontend framework, which is based on TypeScript. It assists developers in creating scalable, contemporary online applications, particularly Single Page Applications (SPAs), in which content updates dynamically rather than requiring a page reload. By employing components and services to arrange our code, it facilitates efficient and maintainable development. We must first establish a clear understanding of Angular's definition, structure, and component placement before lifecycle hooks make any sense.

AngularJS vs Angular (Modern Angular)

Feature AngularJS Angular (2+)
Language JavaScript TypeScript
Architecture MVC Component-based
Mobile Support Poor Excellent
Performance Slower Faster (AOT, Tree Shaking)
Development Support Discontinued Actively maintained
Ecosystem Classic JS ecosystem RxJS, TypeScript, CLI

Here’s how the high-level angular structure looks.

Angular Element Purpose School App Example
Modules Organize the app into functional areas StudentModule, TeacherModule, AdminModule, and TimetableModule group features into manageable sections.
Components Handle UI and logic for individual features StudentListComponent, AttendanceFormComponent, and ExamResultsComponent power the core screens of the app.
Templates Define the view using Angular-enhanced HTML A dynamic report card template uses *ngFor to loop through subjects and display student scores.
Services Share business logic and data access across components StudentService centralizes logic to fetch, add, or update student records from the backend.
Routing Enable navigation between pages Angular Router handles navigation to /students, /teachers, /results, and /library.
Directives Add dynamic behavior to templates *ngIf="isAbsent" highlights students in red if they’re absent during the attendance check.
Pipes Format output in templates {{ dateOfBirth | date:'longDate' }} formats a birthday date

What is a Component in Angular?

The core of the user interface in Angular is a component. Usually, every screen, button, form, or card is implemented as a component, much like the Common Language Runtime (CLR) components in.NET. A component is the fundamental unit of the user interface (UI) in Angular. It holds the HTML template, CSS styling, and TypeScript logic for a view, which is a section of the screen that it controls.

Structure of a Component
1. Class contains the logic and data for the component using TypeScript. And File Extension: .ts
@Component({
  selector: 'app-product',         // We can use <app-product></app-product> in HTML
  templateUrl: './product.html',   // Uses product.html for UI
  styleUrls: ['./product.css']     // Uses product.css for styles
})
export class ProductComponent {    // This class holds logic like product name, price, etc.
  name = 'T-Shirt';
  price = 499;
}


2. Template defines the user interface (UI layout) using HTML. It displays data from the class using Angular's data binding.File Extension: .html
<!-- product.component.html -->
<h2>{{ productName }}</h2>
<p>Price: ₹{{ price }}</p>

3. Style adds styling (colors, fonts, spacing) specific to this component. File Extension: .css or .scss

/* product.component.css */
h2 {
  color: blue;
  font-weight: bold;
}

p {
  font-size: 16px;
}


Why are components important for Lifecycle Hooks?

Lifecycle hooks are embedded within components. So, unless you understand how components are created, rendered, and destroyed, lifecycle hooks won’t mean much. Here’s the flow.

  • Angular initializes a component.
  • Angular runs specific hooks at each stage of that component's life.
  • We use those hooks to run our own logic at the perfect moment (like fetching data, unsubscribing, or calculating total).

Angular Lifecycle Hooks
Lifecycle hooks in Angular are special methods that get called automatically at specific stages of a component’s life, from creation to destruction. Lifecycle hooks let Angular manage the creation, change detection, and destruction of components. This gives us fine control over how and when code runs.

Lifecycle hooks are built-in functions that Angular calls at different moments during a component’s lifetime, like when it's created, updated, or destroyed.
Why Use Lifecycle Hooks?

We use lifecycle hooks to,

  • Run initial setup code (like fetching data when the component loads)
  • Detect changes in inputs
  • Perform cleanup tasks (like clearing timers or unsubscribing from services)
  • Debug the flow of your component.


Hook Name When Called Purpose Usage Example
constructor() When a component instance is created Basic initialization of class members (no Angular bindings yet) console.log('Constructor')
ngOnChanges(changes: SimpleChanges) When @Input() property changes Respond to input property changes this.loadData(changes['userId'].currentValue);
ngOnInit() Once after the first ngOnChanges() Fetch data, initialize bindings this.getDataFromService();
ngDoCheck() Every change detection run Custom change tracking logic detectManualChange();
ngAfterContentInit() After content projected via <ng-content> is initialized Set up logic dependent on projected content console.log('ng-content loaded')
ngAfterContentChecked() After every check of the content projection Respond to changes in projected content validateProjectedTemplate();
ngAfterViewInit() After the component’s view (and child views) are initialized DOM access, @ViewChild operations this.chart.init(this.chartElement.nativeElement);
ngAfterViewChecked() After every check of the component and child views Update logic if template data changes adjustLayout();
ngOnDestroy() Just before Angular destroys the component Cleanup (unsubscribe, clear interval) subscription.unsubscribe();

Conclusion
Understanding Angular’s architecture is essential for building modern, scalable, and maintainable web applications. This article walked through the foundational blocks of Angular, Components, Component Lifecycle Hooks, which provide precise control over how Angular creates, updates, and destroys components.

 



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in