<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: John</title>
    <description>The latest articles on DEV Community by John (@john_4460c2d9b).</description>
    <link>https://dev.to/john_4460c2d9b</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4103638%2F5926927e-7080-47db-838a-3cd698630c18.png</url>
      <title>DEV Community: John</title>
      <link>https://dev.to/john_4460c2d9b</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/john_4460c2d9b"/>
    <language>en</language>
    <item>
      <title>Refresh Token interceptor</title>
      <dc:creator>John</dc:creator>
      <pubDate>Tue, 01 Sep 2026 05:30:31 +0000</pubDate>
      <link>https://dev.to/john_4460c2d9b/refresh-token-interceptor-738</link>
      <guid>https://dev.to/john_4460c2d9b/refresh-token-interceptor-738</guid>
      <description>&lt;p&gt;import { HttpErrorResponse, HttpInterceptorFn } from '@angular/common/http';&lt;br&gt;
import { inject } from '@angular/core';&lt;br&gt;
import { AuthService } from '../services/auth-service';&lt;br&gt;
import { catchError, switchMap, throwError } from 'rxjs';&lt;/p&gt;

&lt;p&gt;export const authInterceptorInterceptor: HttpInterceptorFn = (req, next) =&amp;gt; {&lt;br&gt;
 // const toaster=inject(ToastrService);&lt;br&gt;
 const authService=inject(AuthService);&lt;br&gt;
  const token=localStorage.getItem("access_token");&lt;/p&gt;

&lt;p&gt;// token attach with request&lt;br&gt;
  if (token) {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const clonedRequest = req.clone({
  setHeaders: {
    Authorization: `Bearer ${token}`
  }
});

return next(clonedRequest).pipe(

  catchError((error: HttpErrorResponse) =&amp;gt; {

     let errorMessage = 'An unknown error occurred!';
    if (error.status === 401) {

      return authService.refreshToken().pipe(

        switchMap((response: any) =&amp;gt; {

          console.log('Token refreshed successfully');

          // Save new access token
          localStorage.setItem(
            'access_token',
            response.accessToken
          );

          // Retry original request
          const retryRequest = req.clone({
            setHeaders: {
              Authorization: `Bearer ${response.accessToken}`
            }
          });

          return next(retryRequest);
        }),

        catchError((refreshError) =&amp;gt; {

          console.error(
            'Refresh token failed:',
            refreshError
          );

          // Both tokens are no longer valid
          localStorage.removeItem('access_token');
          localStorage.removeItem('refresh_token');

          return throwError(() =&amp;gt; refreshError);
        })
      );
    }

    if (error.error instanceof ErrorEvent) {
    // Client-side or network error
    errorMessage = `Error: ${error.error.message}`;
  } else {
    // Backend error
    // Customize this based on your backend payload (e.g., error.error.message)
    errorMessage = error.error?.message || error.message;

    // Handle specific status codes globally here if needed (except 401)
    if (error.status === 403) {
      errorMessage = 'You do not have permission to access this resource.';
    }


  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;// Display the error via Toastr&lt;br&gt;
console.log(error.message);&lt;br&gt;
      //toaster.error(errorMessage, &lt;code&gt;Error ${error.status || ''}&lt;/code&gt;);&lt;br&gt;
        return throwError(() =&amp;gt; error);&lt;br&gt;
      })&lt;br&gt;
    );&lt;br&gt;
  }&lt;br&gt;
  return next(req);&lt;br&gt;
};&lt;/p&gt;

</description>
      <category>angular</category>
      <category>programming</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Authentication</title>
      <dc:creator>John</dc:creator>
      <pubDate>Tue, 01 Sep 2026 04:54:36 +0000</pubDate>
      <link>https://dev.to/john_4460c2d9b/authentication-1a7</link>
      <guid>https://dev.to/john_4460c2d9b/authentication-1a7</guid>
      <description>&lt;p&gt;Install-Package Microsoft.EntityFrameworkCore&lt;br&gt;
Install-Package Microsoft.EntityFrameworkCore.SqlServer&lt;br&gt;
Install-Package Microsoft.EntityFrameworkCore.Tools&lt;br&gt;
Install-Package Microsoft.AspNetCore.Identity.EntityFrameworkCore&lt;br&gt;
Install-Package Microsoft.EntityFrameworkCore.Design&lt;br&gt;
Install-Package Microsoft.AspNetCore.Authentication.JwtBearer&lt;br&gt;
Install-Package MediatR -Version 11.1.0&lt;br&gt;
Install-Package MediatR.Extensions.Microsoft.DependencyInjection -Version 11.1.0&lt;br&gt;
Install-Package FluentValidation.AspNetCore&lt;br&gt;
Install-Package FluentValidation.DependencyInjectionExtensions&lt;br&gt;
Add-Migration InitialCreate&lt;br&gt;
Update-Database&lt;/p&gt;

&lt;p&gt;public interface ICurrentUser&lt;br&gt;
 {&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; string? Id { get; }
 string? Email { get; }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;public class CurrentUser : ICurrentUser&lt;br&gt;
 {&lt;br&gt;
     private readonly IHttpContextAccessor _httpContextAccessor;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; public CurrentUser(IHttpContextAccessor httpContextAccessor)
 {
     _httpContextAccessor = httpContextAccessor;
 }
 public string? Id =&amp;gt; _httpContextAccessor.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
 public string? Email =&amp;gt; _httpContextAccessor.HttpContext?.User?.FindFirst(ClaimTypes.Email)?.Value;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;public class ErrorResponse&lt;br&gt;
 {&lt;br&gt;
     public int StatusCode { get; set; }&lt;br&gt;
     public string Message { get; set; } = string.Empty;&lt;br&gt;
     public string? Details { get; set; }&lt;br&gt;
     public DateTime TimeStamp { get; set; } = DateTime.UtcNow;&lt;br&gt;
 }&lt;/p&gt;

&lt;p&gt;public class GlobalExceptionHandler(ILogger logger) : IExceptionHandler&lt;br&gt;
{&lt;br&gt;
    private readonly ILogger _logger = logger;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async ValueTask&amp;lt;bool&amp;gt; TryHandleAsync(
    HttpContext httpContext,
    Exception exception,
    CancellationToken cancellationToken)
{
    _logger.LogError(exception, "Unhandled exception caught by GlobalExceptionHandler: {Message}", exception.Message);

    var (statusCode, message) = MapException(exception);

    var errorResponse = new ErrorResponse
    {
        StatusCode = (int)statusCode,
        Message = message,
        Details = exception.GetType().Name,
        TimeStamp = DateTime.UtcNow
    };

    httpContext.Response.StatusCode = (int)statusCode;
    httpContext.Response.ContentType = "application/json";

    var json = JsonSerializer.Serialize(errorResponse, new JsonSerializerOptions
    {
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase
    });

    await httpContext.Response.WriteAsync(json, cancellationToken);

    // Return true to signal the exception has been handled
    return true;
}


private static (HttpStatusCode statusCode, string message) MapException(Exception exception)
{
    return exception switch
    {
        BadRequestException =&amp;gt; (HttpStatusCode.BadRequest, exception.Message),
        NotFoundException =&amp;gt; (HttpStatusCode.NotFound, exception.Message),
        UnauthorizedException =&amp;gt; (HttpStatusCode.Unauthorized, exception.Message),
        ConflictException =&amp;gt; (HttpStatusCode.Conflict, exception.Message),
        _ =&amp;gt; (HttpStatusCode.InternalServerError, "An unexpected error occurred. Please try again later.")
    };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;builder.Services.AddSwaggerGen(options =&amp;gt;&lt;br&gt;
{&lt;br&gt;
    options.AddSecurityDefinition("bearer", new OpenApiSecurityScheme&lt;br&gt;
    {&lt;br&gt;
        Type = SecuritySchemeType.Http,&lt;br&gt;
        Scheme = "bearer",&lt;br&gt;
        BearerFormat = "JWT",&lt;br&gt;
        Description = "JWT Authorization header using the bearer Scheme"&lt;br&gt;
    });&lt;br&gt;
    options.AddSecurityRequirement(document =&amp;gt; new OpenApiSecurityRequirement&lt;br&gt;
    {&lt;br&gt;
        [new OpenApiSecuritySchemeReference("bearer", document)] = []&lt;br&gt;
    });&lt;br&gt;
});&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  List&amp;lt;Claim&amp;gt; authClaims = [
       new(ClaimTypes.NameIdentifier,user.Id.ToString()),
       new(ClaimTypes.Email,user.Email??string.Empty),
       new(ClaimTypes.Name,user.Name??string.Empty),
      new (JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), 
      // unique id for token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;];&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
