remote service support via Jwt
This commit is contained in:
@ -50,14 +50,5 @@ namespace Oqtane.Services
|
||||
{
|
||||
await PostJsonAsync($"{ApiUrl}/register?email={WebUtility.UrlEncode(email)}", true);
|
||||
}
|
||||
|
||||
public void SetAntiForgeryTokenHeader(string antiforgerytokenvalue)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(antiforgerytokenvalue))
|
||||
{
|
||||
AddRequestHeader(Constants.AntiForgeryTokenHeaderName, antiforgerytokenvalue);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -42,10 +42,5 @@ namespace Oqtane.Services
|
||||
/// <returns></returns>
|
||||
Task RegisterAsync(string email);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the antiforgerytoken header so that it is included on all HttpClient calls for the lifetime of the app
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
void SetAntiForgeryTokenHeader(string antiforgerytokenvalue);
|
||||
}
|
||||
}
|
||||
|
147
Oqtane.Client/Services/RemoteServiceBase.cs
Normal file
147
Oqtane.Client/Services/RemoteServiceBase.cs
Normal file
@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Services
|
||||
{
|
||||
public class RemoteServiceBase
|
||||
{
|
||||
private readonly SiteState _siteState;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
||||
protected RemoteServiceBase(IHttpClientFactory httpClientFactory, SiteState siteState)
|
||||
{
|
||||
_siteState = siteState;
|
||||
_httpClientFactory = httpClientFactory;
|
||||
}
|
||||
|
||||
private HttpClient GetHttpClient()
|
||||
{
|
||||
var httpClient = _httpClientFactory.CreateClient("Remote");
|
||||
if (!httpClient.DefaultRequestHeaders.Contains(HeaderNames.Authorization) && _siteState != null && !string.IsNullOrEmpty(_siteState.AuthorizationToken))
|
||||
{
|
||||
httpClient.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + _siteState.AuthorizationToken);
|
||||
}
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
protected async Task GetAsync(string uri)
|
||||
{
|
||||
var response = await GetHttpClient().GetAsync(uri);
|
||||
CheckResponse(response);
|
||||
}
|
||||
|
||||
protected async Task<string> GetStringAsync(string uri)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await GetHttpClient().GetStringAsync(uri);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
protected async Task<byte[]> GetByteArrayAsync(string uri)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await GetHttpClient().GetByteArrayAsync(uri);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
protected async Task<T> GetJsonAsync<T>(string uri)
|
||||
{
|
||||
var response = await GetHttpClient().GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None);
|
||||
if (CheckResponse(response) && ValidateJsonContent(response.Content))
|
||||
{
|
||||
return await response.Content.ReadFromJsonAsync<T>();
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
protected async Task PutAsync(string uri)
|
||||
{
|
||||
var response = await GetHttpClient().PutAsync(uri, null);
|
||||
CheckResponse(response);
|
||||
}
|
||||
|
||||
protected async Task<T> PutJsonAsync<T>(string uri, T value)
|
||||
{
|
||||
return await PutJsonAsync<T, T>(uri, value);
|
||||
}
|
||||
|
||||
protected async Task<TResult> PutJsonAsync<TValue, TResult>(string uri, TValue value)
|
||||
{
|
||||
var response = await GetHttpClient().PutAsJsonAsync(uri, value);
|
||||
if (CheckResponse(response) && ValidateJsonContent(response.Content))
|
||||
{
|
||||
var result = await response.Content.ReadFromJsonAsync<TResult>();
|
||||
return result;
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
protected async Task PostAsync(string uri)
|
||||
{
|
||||
var response = await GetHttpClient().PostAsync(uri, null);
|
||||
CheckResponse(response);
|
||||
}
|
||||
|
||||
protected async Task<T> PostJsonAsync<T>(string uri, T value)
|
||||
{
|
||||
return await PostJsonAsync<T, T>(uri, value);
|
||||
}
|
||||
|
||||
protected async Task<TResult> PostJsonAsync<TValue, TResult>(string uri, TValue value)
|
||||
{
|
||||
var response = await GetHttpClient().PostAsJsonAsync(uri, value);
|
||||
if (CheckResponse(response) && ValidateJsonContent(response.Content))
|
||||
{
|
||||
var result = await response.Content.ReadFromJsonAsync<TResult>();
|
||||
return result;
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
protected async Task DeleteAsync(string uri)
|
||||
{
|
||||
var response = await GetHttpClient().DeleteAsync(uri);
|
||||
CheckResponse(response);
|
||||
}
|
||||
|
||||
private bool CheckResponse(HttpResponseMessage response)
|
||||
{
|
||||
if (response.IsSuccessStatusCode) return true;
|
||||
if (response.StatusCode != HttpStatusCode.NoContent && response.StatusCode != HttpStatusCode.NotFound)
|
||||
{
|
||||
Console.WriteLine($"Request: {response.RequestMessage.RequestUri}");
|
||||
Console.WriteLine($"Response status: {response.StatusCode} {response.ReasonPhrase}");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool ValidateJsonContent(HttpContent content)
|
||||
{
|
||||
var mediaType = content?.Headers.ContentType?.MediaType;
|
||||
return mediaType != null && mediaType.Equals("application/json", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,24 +5,31 @@ using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Oqtane.Documentation;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Services
|
||||
{
|
||||
[PrivateApi("Don't show in the documentation, as everything should use the Interface")]
|
||||
public class ServiceBase
|
||||
{
|
||||
private readonly HttpClient _http;
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly SiteState _siteState;
|
||||
|
||||
protected ServiceBase(HttpClient client, SiteState siteState)
|
||||
protected ServiceBase(HttpClient httpClient, SiteState siteState)
|
||||
{
|
||||
_http = client;
|
||||
_httpClient = httpClient;
|
||||
_siteState = siteState;
|
||||
}
|
||||
|
||||
private HttpClient GetHttpClient()
|
||||
{
|
||||
if (!_httpClient.DefaultRequestHeaders.Contains(Constants.AntiForgeryTokenHeaderName) && _siteState != null && !string.IsNullOrEmpty(_siteState.AntiForgeryToken))
|
||||
{
|
||||
_httpClient.DefaultRequestHeaders.Add(Constants.AntiForgeryTokenHeaderName, _siteState.AntiForgeryToken);
|
||||
}
|
||||
return _httpClient;
|
||||
}
|
||||
|
||||
// should be used with new constructor
|
||||
public string CreateApiUrl(string serviceName)
|
||||
{
|
||||
@ -95,24 +102,9 @@ namespace Oqtane.Services
|
||||
}
|
||||
}
|
||||
|
||||
// note that HttpClient is registered as a Scoped(shared) service and therefore you should not use request headers whose value can vary over the lifetime of the service
|
||||
protected void AddRequestHeader(string name, string value)
|
||||
{
|
||||
RemoveRequestHeader(name);
|
||||
_http.DefaultRequestHeaders.Add(name, value);
|
||||
}
|
||||
|
||||
protected void RemoveRequestHeader(string name)
|
||||
{
|
||||
if (_http.DefaultRequestHeaders.Contains(name))
|
||||
{
|
||||
_http.DefaultRequestHeaders.Remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task GetAsync(string uri)
|
||||
{
|
||||
var response = await _http.GetAsync(uri);
|
||||
var response = await GetHttpClient().GetAsync(uri);
|
||||
CheckResponse(response);
|
||||
}
|
||||
|
||||
@ -120,7 +112,7 @@ namespace Oqtane.Services
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _http.GetStringAsync(uri);
|
||||
return await GetHttpClient().GetStringAsync(uri);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -134,7 +126,7 @@ namespace Oqtane.Services
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _http.GetByteArrayAsync(uri);
|
||||
return await GetHttpClient().GetByteArrayAsync(uri);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -146,7 +138,7 @@ namespace Oqtane.Services
|
||||
|
||||
protected async Task<T> GetJsonAsync<T>(string uri)
|
||||
{
|
||||
var response = await _http.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None);
|
||||
var response = await GetHttpClient().GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None);
|
||||
if (CheckResponse(response) && ValidateJsonContent(response.Content))
|
||||
{
|
||||
return await response.Content.ReadFromJsonAsync<T>();
|
||||
@ -157,7 +149,7 @@ namespace Oqtane.Services
|
||||
|
||||
protected async Task PutAsync(string uri)
|
||||
{
|
||||
var response = await _http.PutAsync(uri, null);
|
||||
var response = await GetHttpClient().PutAsync(uri, null);
|
||||
CheckResponse(response);
|
||||
}
|
||||
|
||||
@ -168,7 +160,7 @@ namespace Oqtane.Services
|
||||
|
||||
protected async Task<TResult> PutJsonAsync<TValue, TResult>(string uri, TValue value)
|
||||
{
|
||||
var response = await _http.PutAsJsonAsync(uri, value);
|
||||
var response = await GetHttpClient().PutAsJsonAsync(uri, value);
|
||||
if (CheckResponse(response) && ValidateJsonContent(response.Content))
|
||||
{
|
||||
var result = await response.Content.ReadFromJsonAsync<TResult>();
|
||||
@ -179,7 +171,7 @@ namespace Oqtane.Services
|
||||
|
||||
protected async Task PostAsync(string uri)
|
||||
{
|
||||
var response = await _http.PostAsync(uri, null);
|
||||
var response = await GetHttpClient().PostAsync(uri, null);
|
||||
CheckResponse(response);
|
||||
}
|
||||
|
||||
@ -190,7 +182,7 @@ namespace Oqtane.Services
|
||||
|
||||
protected async Task<TResult> PostJsonAsync<TValue, TResult>(string uri, TValue value)
|
||||
{
|
||||
var response = await _http.PostAsJsonAsync(uri, value);
|
||||
var response = await GetHttpClient().PostAsJsonAsync(uri, value);
|
||||
if (CheckResponse(response) && ValidateJsonContent(response.Content))
|
||||
{
|
||||
var result = await response.Content.ReadFromJsonAsync<TResult>();
|
||||
@ -202,7 +194,7 @@ namespace Oqtane.Services
|
||||
|
||||
protected async Task DeleteAsync(string uri)
|
||||
{
|
||||
var response = await _http.DeleteAsync(uri);
|
||||
var response = await GetHttpClient().DeleteAsync(uri);
|
||||
CheckResponse(response);
|
||||
}
|
||||
|
||||
@ -228,7 +220,7 @@ namespace Oqtane.Services
|
||||
// This constructor is obsolete. Use ServiceBase(HttpClient client, SiteState siteState) : base(http, siteState) {} instead.
|
||||
protected ServiceBase(HttpClient client)
|
||||
{
|
||||
_http = client;
|
||||
_httpClient = client;
|
||||
}
|
||||
|
||||
[Obsolete("This method is obsolete. Use CreateApiUrl(string serviceName, Alias alias) in conjunction with ControllerRoutes.ApiRoute in Controllers instead.", false)]
|
||||
|
Reference in New Issue
Block a user