Best Practices for JWT Authentication in Angular Apps

    Monday, June 24, 20249 min read1097 views
    Best Practices for JWT Authentication in Angular Apps

    First of all, we need to know what JWT token means in Angular.

    So, JWT stands for JSON web tokens that are basically used to secure our website. JSON web tokens provide us a secret key we need to store it in local storage for feature use case. By using that key which is stored securely in local storage we can get access to our website or web application.

    How JWT token works?

    In general, when we want to access any website or application like banking, e-commerce, etc we must have login/register interface in which we need to provide our credentials after that we will get access to that application.

    So, when we login at that time we have provided the credentials based on that credentials the server side provides us JWT token. That JWT token we need to store it in local storage for any future request. After we have stored token data in local storage if we want to make any http request to the server side then for verification purpose we need to provide that JWT token alongside http request.

    Authentication and Authorization

    In today's era information security plays a crucial role. Here, in security these two terms i.e Authentication and Authorization are commonly used.

    Authentication

    Authentication is process of verifying the identity of user when trying to access the information or application. In this process the server returns a token after we get user id provide login credentials. And that token is useful for all future requests. The example of authentication is when we provide username/email and password like credentials in login page.

    Authorization

    Authorization is a process of identifying the user has access to some part of the application. Here in authorization process we need to attach token to all the request made to server. Because, by using that token server verifies that who is making the request and provide the respective response to the client side.

    Sections of JWT tokens

    A JWT token consists of three distinct parts that work together to encapsulate and secure data:

    Header

    This section of the token contains information about the algorithm used for token signing and the token type. It specifies how the signed token itself should be verified and interpreted.

    JWT Payload

    Also known as the claims or data section, the payload holds the actual data or information that the token carries. This can include user details, permissions, or any other relevant data needed for authentication and authorization.

    Verify Signature

    The token’s signature is a crucial component for ensuring the integrity and authenticity of the token. It is generated using a secret key or a public key, depending on the chosen signing algorithm.

    Verifying the signature allows the recipient to validate that the token has not been tampered with and originated from a trusted source.

    What happens when the JWT token Expires?

    Every JWT token has a token expiration period and after that, the token expiration is done. When any JWT token expiration is done and we make the HTTP requests then the server-side usually returns 401 unauthorised status. And, for smooth behavior of our web application, we need to handle all the situations that will affect the application's performance.

    Token Refresh

    Refreshing tokens is a common practice in token-based authentication systems like JWT to ensure that users remain authenticated without needing to re-enter their credentials frequently. Here's a general approach to implementing token refresh functionality in an Angular application:

    1. Token Expiry: Set an expiration time for your signed JWT tokens. When a user logs in or obtains a token, include an expiration time (typically in the token payload) indicating when the token will expire.

    2. Token Refresh Endpoint: Create a server-side endpoint specifically for refreshing tokens. This endpoint should accept an expired token and return a new token if the user is still authenticated and the token is refreshable.

    3. Automatic Token Refresh: Implement logic in your Angular application to automatically refresh the token when it is about to expire. You can achieve this by using Angular interceptors to intercept outgoing requests and check if the token is expired. If the token is expired, make a request to the token refresh endpoint to obtain a new token.

    4. Handling Token Expiry Errors: Handle scenarios where the token refresh request fails, such as when the refresh token itself has expired or when the user's session has ended. In such cases, prompt the user to log in again and clear any stored authentication tokens.

    5. Token Storage: Store the refreshed token securely in the client-side storage (e.g., local storage or session storage) after successfully refreshing it. Update the stored token to use the new token for subsequent requests.

    6. Token Interceptor: Use an Angular interceptor to automatically attach the refreshed token to outgoing requests, ensuring that the user remains authenticated for subsequent requests.

    7. Session Expiry Handling: Implement mechanisms to handle user session name expiry gracefully, similar to those used during initial authentication. When a token refresh request fails or the session has ended, redirect the user to the login page and prompt them to log in again.

    By implementing token refresh functionality in your Angular application, you can ensure that users remain authenticated seamlessly without experiencing interruptions due to expired tokens. This improves user experience while maintaining security by periodically refreshing authentication tokens.

    Can JWT Tokens be Decrypted?

    JWT (JSON Web Token) tokens are not encrypted; they are signed. There is a fundamental difference between encryption and signing:

    - Encryption: In encryption, data is transformed into an unreadable format using an encryption algorithm and a secret key. To decrypt the data, the encrypted message is reversed back to its original form using the same algorithm and the correct decryption key.

    - Signing: In signing, a digital signature is generated using a cryptographic algorithm and a secret key. This signature is attached to the data. Verifying the signature involves recalculating it using the same algorithm, the received data, and the secret key. If the recalculated signature matches the received signature, the data hasn't been tampered with.

    JWT tokens are created by encoding a JSON object payload and signing it with a secret key. The signature ensures the integrity of the token, meaning that if the token is tampered with, the signature won't match, and the token will be considered invalid.

    Since JWT tokens are signed, not encrypted, they can be decoded by anyone who has access to them. However, they cannot be tampered with without invalidating the signature, which would cause the token to be rejected during verification.

    Therefore, it's crucial to store JWT tokens securely and not include sensitive information within them unless absolutely necessary.

    Get Top of the class Performance and Code Maintainability 
    Angular Minds’ exclusive
    Angular Development services can bring the latest updates and improve your web application’s performance.

    Vulnerabilities of Angular application

    Angular applications, like any web application, can be susceptible to various security vulnerabilities if not developed and maintained properly. Some common vulnerabilities of Angular applications include:

    1. Cross-Site Scripting (XSS): XSS vulnerabilities occur when untrusted data is rendered in a web page without proper sanitization. Attackers can inject malicious scripts into the application, leading to the execution of arbitrary code in users' browsers. Angular's built-in sanitization features help mitigate XSS vulnerabilities, but developers must still exercise caution and properly sanitize user inputs.

    2. Cross-Site Request Forgery (CSRF): CSRF attacks exploit the trust that a site has in a user's browser by tricking the user into performing unintended actions on a web application.

    Angular applications can be vulnerable to CSRF attacks if they do not implement proper CSRF protection mechanisms, such as CSRF tokens or same-site cookie attributes.

    3. Injection Attacks: Injection attacks, such as SQL injection or command injection, occur when untrusted data is interpreted as part of a query or command, leading to unintended behavior. While Angular's data binding features help prevent most injection attacks, developers should still use parameterized queries and avoid executing user-supplied data in unsafe contexts.

    4. Authentication and Session Management Issues: Improper implementation of authentication and session management can lead to vulnerabilities such as session fixation, session hijacking, or insufficient authentication.

    Developers should follow best practices for implementing secure authentication mechanisms, such as token-based authentication with proper token validation and encrypted token expiration policies.

    5. Insecure Direct Object References (IDOR): IDOR vulnerabilities occur when an application exposes sensitive information or functionality through insecure references to internal objects. Angular applications can be vulnerable to IDOR if they expose sensitive data or functionality through client-side code or APIs without proper authorization checks.

    6. Insecure Deserialization: Insecure deserialization vulnerabilities occur when untrusted data is deserialized without proper validation, leading to arbitrary code execution or other security issues. While Angular itself does not directly handle deserialization, developers should be cautious when working with serialized data received from external sources.

    7. Insecure Communication: Insecure communication between the client and server, such as using HTTP instead of HTTPS, can expose sensitive information to eavesdropping or man-in-the-middle attacks.

    Angular applications should always use HTTPS to encrypt data transmitted over the network and implement other security measures such as a Content Security Policy (CSP) to mitigate communication-related vulnerabilities.

    8. Third-Party Dependencies: Using third-party libraries and dependencies in Angular applications can introduce security vulnerabilities if the libraries themselves have security issues or if they are not kept up-to-date. Developers should regularly update dependencies and libraries to ensure they include the latest security patches and fixes.

    By addressing these vulnerabilities and following security best practices, developers can significantly reduce the risk of security incidents in Angular applications and ensure they remain secure against various threats. Regular security audits, code reviews, and vulnerability assessments are also essential for maintaining the security of Angular applications over time.

    Creating and Storing JWT token

    Creation of a JWT token happens on the server-side when the user login with credentials. When the user provides credentials and the client code makes a request to the server side, the server creates the JWT token and sends it back to the client side. On the client side when we get JWT we need to store that data in local storage.

    Creating and Storing JWT token

    Attaching JWT token using angular interceptor

    Creation of interceptor

    When we have a JWT token and for each request, we need to attach that JWT token for verification purposes. When we pass a token the server verifies or authorizes that user and provides access. For each HTTP request, we need to attach a JWT token in the headers section. And for that purpose, we use an interceptor in angular for attaching JWT token in headers. Because interceptors intercept each request i.e. incoming and outgoing.

    import { Injectable } from '@angular/core';
    import {
      HttpRequest,
      HttpHandler,
      HttpEvent,
      HttpInterceptor
    } from '@angular/common/http';
    import { Observable } from 'rxjs';
    
    @Injectable()
    export class JwtInterceptor implements HttpInterceptor {
    
      constructor() {}
    
      intercept(request: HttpRequest<unknown>, next: HttpHandler):
        Observable<HttpEvent<unknown>> {
        return next.handle(request);
      }
    }

    Registering the interceptor into the app module

    After we have created interceptor we need to register that interceptor into app module. Because when we register our interceptor into app.module then it will start intercepting all the request.

    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    
    import { AppComponent } from './app.component';
    import { HTTP_INTERCEPTORS } from '@angular/common/http';
    import { JwtInterceptor } from './interceptor/jwt.interceptor';
    
    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        BrowserModule,
      ],
      providers: [
        {
          provide: HTTP_INTERCEPTORS,
          useClass: JwtInterceptor,
          multi: true
        }
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

    Can you Decode the JWT Token in Angular?

    Yes, you can decode a JWT (JSON Web Token) token. JWT is a compact, URL-safe means of representing claims to be transferred between two parties. It consists of three parts separated by dots: the header, the payload, and the signature. To decode a JWT token, you can follow these steps:

    1. Split the JWT: Split the JWT token string into its three parts: header, payload, and signature.

    2. Decode each part: Decode the base64url-encoded header and payload. These are JSON strings containing information about the token's algorithm and claims.

    3. Verify signature (optional): If you have the token's secret key, you can verify the signature to ensure the token hasn't been tampered with. This step is optional depending on your use case.

    4. Read the claims: Once decoded, you can access the information contained within the payload. Common claims include issuer, subject, expiration time, and audience.

    5. Use the information: After decoding and verifying the token, you can use the claims for authentication, authorization, or any other relevant purposes within your application.

    Tools like jwt.io provide easy-to-use interfaces for decoding and verifying JWT tokens. However, always exercise caution when handling sensitive information like JWT tokens.

    Is Angular safe from XSS?

    Angular provides built-in features to help prevent cross-site scripting (XSS) attacks, but developers must still adhere to best security practices to ensure application security. Angular's template engine automatically sanitizes user input by default, preventing the execution of potentially harmful scripts. This default behavior significantly reduces the risk of XSS vulnerabilities in Angular applications.

    Angular also offers features like Content Security Policy (CSP) integration, which allows developers to specify trusted sources for scripts, styles, and other resources, further enhancing security against XSS attacks.

    Additionally, Angular's built-in HttpClient module provides protection against XSS by automatically encoding user input before sending it to the server, reducing the likelihood of malicious script injection.

    However, developers must remain vigilant and follow security best practices such as input validation, output encoding, and proper handling of untrusted data. Failure to sanitize inputs or improperly use Angular's features can still leave applications vulnerable to XSS attacks.

    Regular security audits, staying up-to-date with Angular's security features, and following secure coding practices are essential to ensure Angular applications remain safe from XSS vulnerabilities.

    How the refresh token mechanism works

    Implementing a refresh token mechanism in an Angular application using the JWT library involves several steps. Here's a basic guide to set it up:

    1. Server-side Implementation:

    - First, ensure your server-side authentication system supports issuing refresh tokens alongside access tokens.

    - When a user logs in or authenticates, issue both an access token and a refresh token.

    - Store the refresh token securely on the server (usually in a database) associated with the user's account.

    2. Token Storage:

    - After a successful login, store both the access token and the refresh token securely on the client-side. You can use browser local storage, session storage, or HTTP-only cookies based on your security requirements.

    - Make sure to protect sensitive tokens from XSS attacks.

    3. Access Token Expiry Handling:

    - Check the expiration time of the access token before making any protected API requests.

    - If the access token is expired, initiate a token refresh process.

    4. Token Refresh Process:

    - When the access token is expired, use the refresh token to request a new access token from the server.

    - Create an Angular service to handle token refresh logic. This service should send a POST request to the server's refresh token endpoint along with the refresh token.

    - Upon receiving a successful response from the server, update the stored access token with the new one.

    5. HTTP Interceptors:

    - Use Angular HTTP interceptors to intercept outgoing HTTP requests.

    - Check if the request requires authentication and attach the access token to the request headers.

    - If the access token is expired or if the server responds with a 401 Unauthorized status code, trigger the token refresh process.

    - Retry the original request with the new access token if the refresh is successful.

    6. Error Handling:

    - Handle errors gracefully, such as network errors or server errors during the token refresh process.

    - If the refresh token is invalid or expired, log the user out and clear the stored tokens.

    7. Token Revocation:

    - Implement mechanisms to revoke refresh tokens, such as logout functionality.

    - When the user logs out, invalidate the refresh token on the server to prevent unauthorized access.

    8. Automatic Token Refresh:

    - Optionally, implement automatic token refresh logic to periodically check the validity of the access token and refresh it if necessary.

    By following these steps, you can implement a secure refresh token mechanism in your Angular application using JWT for authentication. Make sure to thoroughly test the implementation to ensure proper functionality and security.

    Additonal key points

    HTTP Headers

    HTTP headers are key-value pairs sent between the client and server with each HTTP request and response. They convey information about the request or response, or about the object sent in the message body.

    This likely indicates a section or page in a documentation or book, but generally, HTTP headers are used to pass metadata, such as:

    • Content-Type: Indicates the media type of the resource (e.g., application/json).

    • Authorization: Contains the credentials to authenticate a user agent with a server.

    Application Server

    An application server is a software framework that provides both facilities to create web applications and a server environment to run them.

    This range might refer to documentation, highlighting that application servers manage the backend components of an application, such as business logic, database interactions, and services.

    Bearer Tokens

    Bearer tokens are a type of access token used in OAuth 2.0 to authenticate API requests. The token is called a "bearer" token because whoever bears the token can access the associated resources.

    Indicates the basic understanding that bearer tokens are often included in the Authorization header as Authorization: Bearer <token>.

    Secret Key

    A secret key is a piece of data used in cryptographic operations, often to encrypt and decrypt information or to create digital signatures.

    This might refer to documentation on how to securely store data and use secret keys, emphasizing the importance of keeping them confidential and using them in secure environments.

    User's Data

    User's data refers to any personal or sensitive information about a user that an application might collect, process, or store.

    This likely refers to a basic introduction to handling user's data, emphasizing practices like data privacy, protection, and compliance with regulations (e.g., GDPR).

    Public Key

    A public key is part of a public/private key pair used in asymmetric cryptography. The public key can be shared openly and is used to encrypt data, which can only be decrypted by the corresponding private key.

    Refers to a more detailed explanation of public keys, their uses in encryption and digital signatures, and how they fit into public key infrastructure (PKI).

    Login Service

    A login service is a system or a component that handles user authentication, typically verifying a user's credentials (username and password) and granting access to the system.

    • This basic introduction would cover the essentials of setting up a login service, such as handling user credentials, sessions, and security best practices.

    API Request

    An API request is a call made by a client to a server's API to perform a specific operation, such as retrieving or updating data.

    • Basic coverage includes the structure of an API request, typically involving the HTTP method (GET, POST, etc.), the endpoint URL, headers, and possibly a body with data.

    Web Development

    Web development is the process of creating websites or web applications, encompassing front-end development (client-side) and back-end development (server-side).

    In web development, understanding the above concepts is crucial. Developers need to be familiar with how to use HTTP headers for communication, secure API requests with bearer tokens, handle user's data responsibly, and implement login services effectively.

    Application servers play a critical role in running web applications, and cryptographic keys (public and secret) are fundamental to securing communications and data.

    24
    Share
    Hire Expert Angular Developers
    Hire Expert Angular Developers
    With a customer-centric approach and clean code, the team of developers at Angular Minds is the perfect fit for your next project.
    Hire now

    Related articles

    This website uses cookies to analyze website traffic and optimize your website experience. By continuing, you agree to our use of cookies as described in our Privacy Policy.