If you are writing an application that has it’s authentication with JWT, you might be wondering what is a good method to do this? I’ve used the HttpClient along with Xamarin.Essentials’s Preference tools for this.

To start out, I use the Preferences to store my token and refresh token. We also set our BaseAddress. Doing this allows us to switch from Dev, QA, and Production environments without touching every service.

    public class JWTHttpClient : HttpClient
    {
        public static string Token
        {
            get => Xamarin.Essentials.Preferences.Get(nameof(Token), "");
            set => Xamarin.Essentials.Preferences.Set(nameof(Token), value);
        }
        public static string RefreshToken
        {
            get => Xamarin.Essentials.Preferences.Get(nameof(RefreshToken), "");
            set => Xamarin.Essentials.Preferences.Set(nameof(RefreshToken), value);
        }

        public JWTHttpClient()
        {
            // Set your base address
            BaseAddress = new Uri("http://www.ptdave.com");
            if (!string.IsNullOrEmpty(Token))
            {
                DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", JWTHttpClient.Token);
            }
        }
    }

Now this gives us all of our normal functions that we need in to make our Get, Post, Patch, and Delete and our header is already added. When we do a login / logout we just set our tokens to empty strings and that will prevent any new clients from getting the request.

Example usage may look like this:

try
{
    using (var client = new JWTHttpClient())
    {
        var request = await client.GetAsync("/");
        if (request.IsSuccessStatusCode)
        {
            // Handle any decoding here
        }
        else
        {
            // Throw or return an error response of some kind
        }
    }
}
catch(Exception ex)
{
    // There is a possibility that something happened. Be ready to catch it here. 

}

Handling refreshing is something you will want to decide how to implement. Personally, I think it is better to write your own Get, Post, Put, Patch, Delete methods that have a refresh built in.

Depending on how your API is setup though, your code will be different. Here is an example of how it might look. You will need to fill in the CheckRefresh for your own project based on the information that you already have or libraries installed.

/// <summary>
        /// Refreshes the token if necessary, if we were unable to and needed to return false
        /// </summary>
        /// <returns>
        /// True is successful or unnecessary
        /// False is unsuccessful or a failure
        /// </returns>
        public async Task<bool> CheckRefresh()
        {
            // Determine if your token is expired, if so refresh



            return true;
        }

        public async Task<HttpResponseMessage> GetAPIAsync(string path)
        {
            // Check our Token using CheckRefresh
            try
            {
                if (!await CheckRefresh())
                {
                    throw new TokenException("Unable to refresh token");
                }
            }
            catch (Exception ex)
            {
                throw new TokenException("Error refreshing token", ex);
            }

            return await GetAsync(path);
        }

        public async Task<HttpResponseMessage> PostAPIAsync(string path, HttpContent content)
        {
            try
            {
                if (!await CheckRefresh())
                {
                    throw new TokenException("Unable to refresh token");
                }
            }
            catch(Exception ex)
            {
                throw new TokenException("Error refreshing token", ex);
            }
            

            return await PostAsync(path, content);
        }

        public class TokenException : Exception
        {
            public TokenException() : base()
            {

            }
            public TokenException(string msg) : base(msg)
            {

            }
            public TokenException(string msg, Exception inner) : base(msg,inner)
            {

            }
        }

Notice the TokenException, it will throw if we could not refresh the token. So this is potentially something your service or caller will need to handle. Why? You may be denied or disabled if you can’t refresh.

Conclusion

This is not intended for your to copy and paste in, but more of a outline of how you can implement your own with Xamarin. I may improve on this as time goes on, so come back and visit.