Lucas Dev https://lucasgdev.com Mon, 22 Jul 2024 23:32:09 +0000 en-US hourly 1 https://lucasgdev.com/wp-content/uploads/2024/05/cropped-LD-removebg-preview-32x32.png Lucas Dev https://lucasgdev.com 32 32 Securing Your ASP.NET Core Apps with JWT Authentication https://lucasgdev.com/securing-your-asp-net-core-apps-with-jwt-authentication/?utm_source=rss&utm_medium=rss&utm_campaign=securing-your-asp-net-core-apps-with-jwt-authentication Mon, 22 Jul 2024 23:32:09 +0000 https://lucasgdev.com/?p=429 In today’s web development landscape, robust authentication mechanisms are crucial. JWT (JSON Web Token) has emerged as a popular choice due to its simplicity, security, and flexibility. This blog post will delve into using JWT for authentication in ASP.NET Core applications.

Imagine a secure vault protecting your application’s valuable data. Users need proper credentials to access this vault. JWT acts like a digital key that allows authorized users to access specific resources within your application.

What is JWT?

JWT is an open standard (RFC 7519) for securely transmitting information between parties as a JSON object. It consists of three parts.

  1. Header: Contains information about the token type (JWT) and the signing algorithm used.
  2. Payload: Carries the actual claims or data about the user, such as username, ID, roles, etc.
  3. Signature: Ensures the integrity of the token. It’s created by hashing the header and payload with a secret key known only to the server.

Benefits of Using JWT Authentication:

  • Stateless: JWTs are self-contained, eliminating the need for server-side session management. This improves scalability and simplifies application architecture.
  • Security: JWTs are signed and can be configured to expire, preventing unauthorized access and mitigating session hijacking risks.
  • Cross-Origin Resource Sharing (CORS): JWTs can be easily used for authorization across different origins, making them suitable for Single-Page Applications (SPAs) and microservices architectures.

Implementing JWT Authentication in ASP.NET Core:

Here’s a basic overview of the steps involved:

  1. Install Packages: You’ll need to install the Microsoft.AspNetCore.Authentication.JwtBearer NuGet package to enable JWT Bearer token authentication.
  2. Configure JWT Options: Define the signing algorithm, secret key, token lifetime, and issuer in your application configuration.
  3. User Registration and Login: During user registration, store relevant user information securely. Upon successful login, generate a JWT token containing user claims.
  4. Securing Endpoints: Use middleware or authorization filters to protect specific API endpoints. These checks will validate the presence and authenticity of the JWT token before granting access.
  5. Client-Side Integration: On the client-side (web or mobile app), store the JWT token securely (e.g., local storage) and send it with authorization headers in subsequent requests to access protected resources.

Additional Considerations:

  • Token Refresh: Implement a mechanism to refresh expiring tokens before they become invalid.
  • Revocation: Consider strategies for blacklisting or revoking compromised tokens.
  • Security Best Practices: Always use strong cryptographic algorithms and follow secure coding practices when handling JWTs.

JWT authentication offers a robust and versatile approach to secure your ASP.NET Core applications. By understanding its principles and implementation steps, you can leverage JWT to build secure and scalable web APIs. Remember to prioritize security best practices throughout the process to ensure the integrity of your user authentication system.

]]>
Reactive Forms – More Control, More Flexibility, And A Better Way to Validate Inputs https://lucasgdev.com/reactive-forms-more-control-more-flexibility-and-a-better-way-to-validate-inputs/?utm_source=rss&utm_medium=rss&utm_campaign=reactive-forms-more-control-more-flexibility-and-a-better-way-to-validate-inputs Mon, 15 Jul 2024 19:41:54 +0000 https://lucasgdev.com/?p=420 When developing forms within Angular applications, traditional template-driven approaches can become unwieldy when managing intricate data structures and implementing robust validation checks. Reactive Forms offer a compelling alternative, providing a structured and predictable paradigm for form data management and validation, streamlining the development process.

Here’s what sets Reactive Forms apart:

  • Model-Driven Approach: You define a model class representing the form data structure, giving you a clear picture of your form’s state.
  • Reactive Observables: You leverage the power of Observables to track changes in form controls and react accordingly. This leads to a more dynamic and reactive form experience.
  • Improved Testability: Reactive Forms are easier to unit test due to their clear separation of concerns between the template and the component logic.
  • Form Validation: Implementing validation rules becomes more straightforward and centralized, improving the overall robustness of your forms.

Building a Reactive Form in Angular:

Here’s a step-by-step breakdown of creating a simple reactive form in Angular:

  • 1) Import the ReactiveFormsModule: You’ll need to import the ReactiveFormsModule from @angular/forms in your app module.
  • 2) Create a FormGroup in the Component: In your component, inject the FormBuilder service from @angular/forms and use it to create a FormGroup instance.

This group will hold all the form controls:

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-reactive-form-example',
  templateUrl: './reactive-form-example.component.html',
  styleUrls: ['./reactive-form-example.component.css']
})
export class ReactiveFormComponentExample {
  userForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.userForm = this.fb.group({
      username: ['', Validators.required],
      email: ['', [Validators.required, Validators.email]]
    });
  }
}

Here, the fb.group method creates a FormGroup with two form controls: username and email. The empty string '' represents the initial value, and the array defines validation rules (e.g., Validators.required for mandatory fields, Validators.email for email format).

  • 3) Bind the FormGroup to the Template: In your component’s template, use the formGroup directive to bind the userForm to the form element:
<form [formGroup]="userForm" (ngSubmit)="onSubmit()">
  <label for="username">Username:</label>
  <input type="text" id="username" formControlName="username">

  <label for="email">Email:</label>
  <input type="email" id="email" formControlName="email">

  <button type="submit">Submit</button>
</form>
  • 4) Handle Form Submission (Optional): In your component, define a method to handle form submission. You can access the form data using the value property of the userForm:
onSubmit() {
  console.log(this.userForm.value);
}

Benefits of Using Reactive Forms:

  • Increased Control: You have more control over the form’s behavior and validation.
  • Improved Maintainability: The separation of concerns between template and logic makes the code easier to understand and maintain.
  • Error Handling: Reactive Forms offer better error handling capabilities through observables.
  • Testability: Unit testing becomes more straightforward due to the clear separation of concerns.

Who Should Use Reactive Forms?

Reactive Forms are ideal for complex forms with intricate validation requirements, dynamic behavior, and a need for better testability. For simpler forms, template-driven forms might still be sufficient.

]]>
Angular Directives – Overview https://lucasgdev.com/angular-directives-overview/?utm_source=rss&utm_medium=rss&utm_campaign=angular-directives-overview Wed, 03 Jul 2024 13:40:15 +0000 https://lucasgdev.com/?p=402 Angular Directives: Powerful Tools to Shape Your User Interface

Angular directives are helpers in your Angular applications. They extend the capabilities of HTML elements, adding dynamic behavior and customization options. With directives, you can manipulate the DOM, control data flow, and enhance the interactivity of your web applications.

Imagine building a house. Regular HTML elements are like the bricks that form the basic structure. But to make your house functional and interesting, you need additional features like doors, windows, and electrical wiring. Directives act as those special features, bringing dynamism and functionality to your Angular components.

Types of Angular Directives:

There are three main categories of directives, each serving a specific purpose:

1) Component Directives: These are the most powerful type, forming the foundation of reusable UI components in Angular. They define a component’s template, styles, and logic, creating encapsulated building blocks for your application. Example:

@Component({
  selector: 'app-product-card',
  templateUrl: './product-card.component.html',
  styleUrls: ['./product-card.component.css']
})
export class ProductCardComponent {
  ...
}

Here, the @Component decorator defines a component directive named app-product-card. It specifies the template, styles, and a class responsible for the component’s logic.

2) Structural Directives: These directives manipulate the DOM structure based on certain conditions. They can add, remove, or modify elements in the template dynamically. Example:

<ul *ngIf="showProducts">
  <li *ngFor="let product of products">{{ product.name }}</li>
</ul>

In this example, the *ngIf directive conditionally renders the <ul> element only if the showProducts variable is true. The *ngFor directive iterates through the products array and dynamically creates <li> elements for each product.

3) Attribute Directives: These directives modify the attributes or behavior of existing HTML elements. They offer a way to extend the functionality of standard HTML elements. Example:

<button [disabled]="!isValid">Save</button>
<p [style.color]="error ? 'red' : 'black'">Error message</p>

The [disabled] directive binds the disabled attribute of the button to the isValid variable, enabling or disabling the button based on the condition. The [style.color] directive dynamically sets the color style of the paragraph based on the error variable.

Benefits of Using Directives:

  • Code Reusability: Directives promote code reuse by encapsulating common UI logic and behavior. You can create reusable directives for functionalities like error handling, data formatting, or custom animations.
  • Improved Readability: Directives enhance the readability of your templates by separating structural logic and data binding from the HTML markup. This leads to cleaner and more maintainable code.
  • Dynamic UI: Directives allow you to create dynamic and interactive user interfaces. You can conditionally render content, modify element styles, and respond to user interactions seamlessly.

Examples in Action:

Imagine you’re building an e-commerce application. Here’s how directives can come into play:

  • A ProductRatingDirective could display a star rating based on a product’s rating value.
  • A HighlightDirective could change the background color of a search term match within a paragraph.
  • A ShowForAuthorizedUsersDirective could conditionally display content only for logged-in users.

By effectively using directives, you can build rich, interactive, and dynamic user interfaces that enhance the user experience in your Angular applications.

Angular directives are not magic, but they are powerful tools that can significantly improve the way you build your applications. By understanding the different types of directives and their functionalities, you can unlock a new level of control and flexibility in your Angular development.

]]>
LeetCode #1929 – Concatenation of Array https://lucasgdev.com/leetcode-1929-concatenation-of-array/?utm_source=rss&utm_medium=rss&utm_campaign=leetcode-1929-concatenation-of-array Wed, 03 Jul 2024 13:37:30 +0000 https://lucasgdev.com/?p=412 Let’s solve LeetCode 1929 – Concatenation of Array problem. It’s from the Arrays section on LeetCode, and as usual, we’ll tackle it using C# today.

Before we jump into the code, let’s understand the problem statement.

This problem challenges you to create a new array by “duplicating” a given integer array. The resulting array should have twice the length of the original, with each element from the original array appearing twice consecutively (That’s the key to solve this challenge).

Understanding the Problem:
  • We are given an integer array nums of length n.
  • We need to create a new array ans of length 2n (twice the length of the original).
  • The elements in the new array ans should be arranged such that ans[i] == nums[i] and ans[i + n] == nums[i] for all indices i from 0 to n-1.

In simpler terms, the new array ans is the concatenation of two copies of the original array nums.

Alright, let’s start designing our solution:

1) We need to create a new array ans that can hold twice the number of elements as the original array nums.

public class Solution {
    public int[] GetConcatenation(int[] nums) {
        int[] ans = new int[nums.Length*2];
    }
}

2) We need to iterate through each element in the original array nums and copy it to the new array ans at two specific positions ( i and i + nums.Length).

public class Solution {
    public int[] GetConcatenation(int[] nums) {
        int[] ans = new int[nums.Length*2];
        
        for(int i = 0; i < nums.Length; i++){
            ans[i] = nums[i];
            ans[i + nums.Length] = nums[i];
        }
    }
}
  • The line ans[i] = nums[i] copies the element at index i from nums to the corresponding index i in the ans array. This ensures the first half of the ans array is a copy of the original nums.
  • The line ans[i + nums.Length] = nums[i] is the key part for concatenation. It copies the same element at index i from nums to an index that is nums.Length positions ahead of the current index i in the ans array. This effectively places a copy of each element from nums in the second half of the ans array.

3) Now we just need to return ans after the loop!

public class Solution {
    public int[] GetConcatenation(int[] nums) {
        int[] ans = new int[nums.Length*2];
        
        for(int i = 0; i < nums.Length; i++){
            ans[i] = nums[i];
            ans[i + nums.Length] = nums[i];
        }
        
        return ans;
    }
}

This solution iterates through the original array, copies each element to its corresponding position in the first half of the new array, and then copies it again to the calculated position in the second half, resulting in the desired concatenation.

This is the result for this solution:

]]>
DTOs in C#: Streamlining Data Flow in Your Applications https://lucasgdev.com/dtos-in-c-streamlining-data-flow-in-your-applications/?utm_source=rss&utm_medium=rss&utm_campaign=dtos-in-c-streamlining-data-flow-in-your-applications Thu, 20 Jun 2024 12:52:04 +0000 https://lucasgdev.com/?p=394 In the world of software development, data is king. But how you handle that data can make a big difference in the efficiency and maintainability of your application. Enter Data Transfer Objects (DTOs), unsung heroes that play a crucial role in keeping your data flow smooth and organized.

Imagine a bustling city. Data is like the people moving around. They need to get from one place (a layer in your application) to another (another layer or a different application altogether). But you wouldn’t send everyone with all their belongings on every trip, right? That would be slow and cumbersome.

DTOs are like taxis for your data. They are lightweight objects designed to carry only the specific data needed for a particular task or communication between different parts of your application. This keeps things efficient and focused.

Here is an example of a DTO in C#:

Imagine you have an e-commerce application and you want to display a list of products on a web page. Each product has a detailed representation in your application’s data model, including attributes like ID, name, description, price, and images. However, for the product listing page, you only need to display a subset of this information, such as the product ID, name, price, and an image thumbnail.

To avoid sending the entire product entity across layers, you can create a ProductDTO class that represents the data structure you need for the product listing:

public class ProductDTO
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public string ImageUrl { get; set; }
}

In your application’s service layer, you can retrieve the products from the data store and map them to ProductDTO objects:

public class ProductService
{
    private readonly IProductRepository _productRepository;

    public ProductService(IProductRepository productRepository)
    {
        _productRepository = productRepository;
    }

    public List<ProductDTO> GetProductsForListing()
    {
        var products = _productRepository.GetAllProducts();
        var productDTOs = new List<ProductDTO>();

        foreach (var product in products)
        {
            productDTOs.Add(new ProductDTO
            {
                ProductId = product.ProductId,
                Name = product.Name,
                Price = product.Price,
                ImageUrl = product.ImageUrl
            });
        }

        return productDTOs;
    }
}

Here’s why DTOs are so valuable:

  • Reduced Payload Size: By sending only the essential data, DTOs minimize the amount of information that needs to be transferred. This is especially important for network communication or when dealing with large datasets.
  • Improved Decoupling: DTOs help to isolate different layers of your application. The data structure of a DTO can be tailored to the specific needs of the receiving layer, without exposing the internal structure of the originating layer’s entities. This promotes loose coupling and makes your code more maintainable.
  • Enhanced Security: DTOs can help to prevent over-posting vulnerabilities. By controlling what data is included in a DTO, you can restrict what information can be modified through external requests.
  • Flexibility and Reusability: DTOs are not tied to specific data sources or persistence mechanisms. You can create different DTOs for different purposes, making them highly reusable throughout your application.

Here’s a typical scenario where DTOs come in handy:

  • You have a complex data model representing a customer in your application. When displaying customer information on a web page, you might only need a subset of that data, such as name, contact details, and purchase history. Instead of sending the entire customer entity across layers, you can create a CustomerDto containing just the necessary properties.

Creating DTOs is a straightforward process. You define classes that mirror the data structure you want to transfer, but only include the relevant properties. There are no special requirements or annotations needed.

DTOs are a simple yet powerful concept that can significantly improve the design and performance of your C# applications. By adopting DTOs, you can achieve cleaner separation of concerns, reduce data overhead, and create a more maintainable codebase. So, the next time you’re working with data flow in your C# projects, consider using DTOs to keep your data moving smoothly and efficiently.

]]>
Entity Framework – Overview https://lucasgdev.com/net-entity-framework-overview/?utm_source=rss&utm_medium=rss&utm_campaign=net-entity-framework-overview Thu, 20 Jun 2024 12:48:48 +0000 https://lucasgdev.com/?p=388 Imagine this: you’re building a fantastic web application, but every time you need to interact with the database, you have to write raw SQL queries. It’s slow, error-prone, and can be a real drag on your development process. Enter Entity Framework (EF), a powerful tool that simplifies how you work with databases in your .NET applications.

Think of EF as a translator. On one side, you have your application code, written in a high-level language like C#. On the other side, you have the relational database, which speaks its own language (SQL). EF acts as the bridge between these two worlds.

Here’s how it works:

  • Modeling Your Data: You start by defining your application’s data model using classes that represent real-world entities, like customers, products, or orders. These classes have properties that map to the columns in your database tables.
  • Automatic Mapping: EF uses a technique called Object-Relational Mapping (ORM) to automatically translate between your object model and the underlying database schema. You don’t need to write complex SQL queries by hand!
  • LINQ for Queries: Instead of writing raw SQL, you can use LINQ (Language Integrated Query) to interact with your data. LINQ allows you to write queries that look very similar to working with objects in your C# code. EF takes care of translating those LINQ queries into efficient SQL queries that the database can understand (This really improves the development experience).

Here’s a simple example using EF Core and LINQ to show how it works:

Let’s create a class named Product and add the following properties:

public class Product
{
  public int ProductId { get; set; }
  public string Name { get; set; }
  public decimal Price { get; set; }
}

This class represents a simple product entity with properties for ID, name, and price.

The class below defines the DbContext, which acts as the bridge between your application and the database. It has a DbSet property for the Product entity, essentially creating an in-memory representation of your database table. The OnConfiguring method specifies the connection string for your database (You could also configure the connection to your database on the program.cs file).

public class DataContext : DbContext
{
  public DbSet<Product> Products { get; set; }

  protected override void OnConfiguring(DbContextOptionsBuilder      optionsBuilder)
  {
    // Replace "YourConnectionString" with your actual connection      string
    optionsBuilder.UseSqlServer("YourConnectionString");
  }
}

We can now use LINQ to query the items from our database, let’s see how we would do it:

public class Program
{
  public static void Main(string[] args)
  {
    // Create the DbContext instance
    using (var context = new DataContext())
    {
      // Sample data
      context.Products.Add(new Product { Name = "T-Shirt", Price = 19.99m });
      context.Products.Add(new Product { Name = "Laptop", Price = 799.99m });
      context.SaveChanges(); // Save changes to the database

      // Use LINQ to query products
      var discountedProducts = context.Products
        .Where(p => p.Price > 20) // Filter products with price > $20
        .OrderByDescending(p => p.Price) // Order by price descending
        .ToList(); // Convert the results to a list

      // Print the results
      foreach (var product in discountedProducts)
      {
        Console.WriteLine($"Product Name: {product.Name}, Price: ${product.Price}");
      }
    }
  }

This code first creates a DbContext instance, and then adds some sample products. The SaveChanges method persists these changes to the database.

The interesting part is the LINQ query. Here’s what’s happening:

  • .Where(p => p.Price > 20): This filters the products where the price is greater than 20 (dollars, euros, etc).
  • .OrderByDescending(p => p.Price): This orders the results by price in descending order.
  • .ToList(): This converts the results of the query into a list of Product objects.

Finally, the code iterates through the list and prints the product name and price.

This is a very basic example, but it demonstrates how EF and LINQ work together. You can use LINQ to perform various operations on your data model, and EF translates those operations into efficient SQL queries behind the scenes.

]]>
Angular – Components Overview https://lucasgdev.com/angular-components-overview/?utm_source=rss&utm_medium=rss&utm_campaign=angular-components-overview Wed, 05 Jun 2024 21:58:09 +0000 https://lucasgdev.com/?p=368 Let’s dive into the world of Angular components and explore how they can make your applications shine!

In Angular, components are the fundamental, reusable building blocks that you use to construct the user interface (UI) of your web application. They’re like Lego bricks that you can assemble and reuse to create more complex UIs.

Here’s a breakdown of what components are and what they do:

– As Building Blocks:
  • Imagine your Angular application’s UI as a big picture. Components are like the individual sections or modules that make up that picture.
  • Each component controls a specific part of the UI, like a header, a navigation bar, a product listing, or a login form.
– Structure of a Component:

A component typically consists of three parts working together

  • Template (HTML): This defines the visual structure of the component using HTML elements. It’s like the blueprint for how things will look on the screen.
  • TypeScript Class: This handles the component’s logic and data. It contains code written in TypeScript that controls how the component behaves and interacts with data.
  • Styles (CSS, SCSS, etc): This defines the visual style of the component using CSS. It determines how the component looks, including fonts, colors, and layout.

In Angular, a component’s selector (‘app-root’ in this example) “acts” like an ID tag. It tells Angular how to recognize and render the component in your HTML templates.

This is how you would use the component above:

<app-root></app-root>

Benefits of Components

  • Reusable: A key advantage of components is reusability. You can create a component once and then use it multiple times throughout your application, with different data or configurations if needed. This saves you time and effort in development.
  • Maintainable: Components help to organize your code in a modular way. This makes your application easier to understand, maintain, and modify.
  • Isolation: Components isolate their functionality and data. This makes it easier to debug issues and prevent unintended side effects in your application.

By understanding components, you have the foundation for building well-structured and maintainable Angular applications.

]]>
LeetCode #1 – Two Sum https://lucasgdev.com/leetcode-1-two-sum/?utm_source=rss&utm_medium=rss&utm_campaign=leetcode-1-two-sum Thu, 16 May 2024 15:41:55 +0000 https://lucasgdev.com/?p=346 Let’s solve LeetCode 1 – Two Sum problem. It’s from the Arrays section on LeetCode, and we’ll tackle it using C# today.

There are often multiple ways to solve an algorithm. However, it’s crucial to consider the time and space complexity of your code. This is where Big O notation comes in. Understanding Big O notation is essential for developers to write efficient, scalable, and performant code.

Before we jump into the code, let’s understand the problem statement.

While the problem description itself is straightforward, finding the optimal solution can be tricky. You might initially consider using nested loops, which would result in a time complexity of O(n^2). This is not ideal for larger datasets due to scalability concerns. Fortunately, there are more efficient approaches available!

To solve this efficiently, let’s create a dictionary, and store each number of the array as its key, and the number’s index as its value. Our dictionary will look like this:

public class Solution {
    public int[] TwoSum(int[] nums, int target) {
        IDictionary<int, int> dict = new Dictionary<int, int>();
    }
}

We’ll create an array to store the solution: the indexes of the two numbers that sum to the target:

public class Solution {
    public int[] TwoSum(int[] nums, int target) {
        IDictionary<int, int> dict = new Dictionary<int, int>();
        var result = new int[2];
    }
}

This step might seem a bit tricky, so follow along closely.

We’ll iterate through the nums array. For each number, we’ll check if the dictionary contains a key equal to the difference between the target sum (target) and the current number of the loop. Remember, the dictionary keys are the numbers from the nums array.

Here’s why we check this: if the difference exists in the dictionary, it means the current number and the value stored for that key (which is the difference) add up to the target sum. These are the two numbers we’re looking for! And then we just have to assign these two numbers to the array we created earlier:

public class Solution {
    public int[] TwoSum(int[] nums, int target) {
        IDictionary<int, int> dict = new Dictionary<int, int>();
        var result = new int[2];

        for(int i = 0; i < nums.Length; i++){
            if(dict.ContainsKey(target - nums[i])){
                result[0] = dict[target - nums[i]];
                result[1] = i;
            }        
        }
    }
}

Since the dictionary is initially empty, we need to populate it with the numbers from the nums array and their corresponding indexes. This is crucial because the if statement we are using checks for the difference between the target sum and a number from the array. By storing the numbers and their indexes in the dictionary, we can efficiently look up the complement (the difference). So, below the if statement we need to add:

public class Solution {
    public int[] TwoSum(int[] nums, int target) {
        IDictionary<int, int> dict = new Dictionary<int, int>();
        var result = new int[2];

        for(int i = 0; i < nums.Length; i++){
            if(dict.ContainsKey(target - nums[i])){
                result[0] = dict[target - nums[i]];
                result[1] = i;
            }
            dict[nums[i]] = i;     
        }
    }
}

Now, we just need to return the result array after the loop!

public class Solution {
    public int[] TwoSum(int[] nums, int target) {
        IDictionary<int, int> dict = new Dictionary<int, int>();
        var result = new int[2];

        for(int i = 0; i < nums.Length; i++){
            if(dict.ContainsKey(target - nums[i])){
                result[0] = dict[target - nums[i]];
                result[1] = i;
            }
            dict[nums[i]] = i;            
        }
        return result;
    }
}

With this solution, our runtime beats 94.16% of users with C#!

]]>