reactiveui / refit

The automatic type-safe REST library for .NET Core, Xamarin and .NET. Heavily inspired by Square's Retrofit library, Refit turns your REST API into a live interface.
https://reactiveui.github.io/refit/
MIT License
8.66k stars 745 forks source link

Error reading cookie using JSRuntime in AuthHeaderHandler #1316

Open nssidhu opened 2 years ago

nssidhu commented 2 years ago

Describe the bug

I am getting the following error, only when adding AddHttpMessageHandler.

{System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.AspNetCore.Components.WebView.Services.WebViewJSRuntime.BeginInvokeJS(Int64 taskId, String identifier, String argsJson, JSCallResultType resultType, Int64 targetInstanceId) at Microsoft.JSInterop.JSRuntime.InvokeAsync[String](Int64 targetInstanceId, String identifier, CancellationToken cancellationToken, PublicKeyToken=7cec85d7bea7798e]].MoveNext()Object[] args) at Microsoft.JSInterop.JSRuntime.d__16`1[[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext() at SharedClassLibrary.RefitAuthHeaderHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in C:\Users\admin\Source\Repos\XXXX\XXXXXHybridApp\SharedClassLibrary\RefitAuthHeaderHandler.cs:line 26}

it this line that throws error var token = await _jsRuntime.InvokeAsync<string>("localStorage.getItem", JsAuthTokenName);

when i debug i do see it like this image

Here my Auth Handler class Note: i had to comment InnerHandler line

using Microsoft.JSInterop;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace SharedClassLibrary
{
    public class RefitAuthHeaderHandler : DelegatingHandler
    {
        private readonly IJSRuntime _jsRuntime;
        private string JsAuthTokenName = "XXXXXAuthToken";

        public RefitAuthHeaderHandler(IJSRuntime jsRuntime)
        {
            // InnerHandler = new HttpClientHandler();
            _jsRuntime = jsRuntime;
        }

        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            try
            {
                var token = await _jsRuntime.InvokeAsync<string>("localStorage.getItem", JsAuthTokenName);

                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);

            }
            catch (Exception ex)
            {
                Console.Error.WriteLine("Not able to get Token in AuthHandler :- " + ex.Message);
            }

            return await base.SendAsync(request, cancellationToken).ConfigureAwait(false); ;
        }
    }
}

Now i am using JSRuntime in other places and i noticed that in those other place there is a value for the _ipcSender

image

Expected behavior JSRuntime should not throw Error

Screenshots

Environment

I am using Visual Studio 2022 Version 17.1.0 Preview 6.0 using .NET 6.0

The error is showing up when running for android.

nssidhu commented 2 years ago

Adding some more information on DI. I have tried Singleton & Scoped as well

builder.Services.AddTransient<RefitAuthHeaderHandler>();

            var setting = new RefitSettings
            {
                ContentSerializer = new NewtonsoftJsonContentSerializer(
                            new JsonSerializerSettings
                            {
                                ContractResolver = new CamelCasePropertyNamesContractResolver()
                            })
            };

            builder.Services.AddRefitClient<IXXXXHttpAPI>(setting)
            .ConfigureHttpClient(c =>
                {
                    c.BaseAddress = new System.Uri("https://XXXXXappdev.azurewebsites.net/api");

                })
            .AddHttpMessageHandler<RefitAuthHeaderHandler>();