Open Lukeuke opened 1 year ago
I also have a similar need, the GQL server I'm hitting requires some custom headers for some queries. I need to be able to supply custom headers to a subset of requests and with dynamic values.
Just to preempt the obvious point that this may not be an ideal design, as the API consumer, the design is not in my control and I just need to consume the API as it is.
I'm not a fan of supplying headers via static methods but I think there are some options for very nice solutions.
ExecuteAsync
can unconditionally accept an optional headers
parameter.
Given that enabling this on all queries could be a breaking change unless the new parameter is added after the cancellationToken
parameter, which would be awkward, this feature could be enabled for a given query based on some annotation in the .graphql
file, something like this:
#[ACCEPT_HEADERS]
query GetMessages {
...
}
Queries defined in .graphql
files can specify some annotation to inform the framework to accept specific header params for the request, something like this:
#[HEADER(x-required-header: String!)]
#[HEADER(x-optional-header: String)]
query GetMessages($param1 String, $param2: Int) {
...
}
so that the query accepts the header parameters as it does other arguments like this GetMessages.ExecuteAsync(param1: "whatever", param2: 10, xRequiredHeader: "some value" )
(granted this approach would require handling of kabab cased headers and
after looking around a bit I found https://github.com/ChilliCream/graphql-platform/issues/5204 and https://github.com/ChilliCream/graphql-platform/issues/3467 which seem to overlap this this issue.
the proposal in https://github.com/ChilliCream/graphql-platform/issues/3467 seems similar to my annotation concept except that its using directives (a feature I'm not familiar with) which seems better being that its code and not just comments
@danny-zegel-zocdoc
I got around the problem by just implemeting the TokenStore
which stores the token in Services as Singleton
public class TokenStore
{
public string Jwt { get; set; } = null!;
}
In Program.cs
:
builder.Services.AddSingleton<TokenStore>();
...
builder.Services.AddHttpClient(
CryptoClient.ClientName,
(service, client) =>
{
var store = service.GetRequiredService<TokenStore>();
client.BaseAddress =
client.BaseAddress = new Uri("http://localhost:5106/graphql");
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", store.Jwt); // Here you can add the header with any value you want and then
// just modify on runtime, Example below
});
Example: When loggin the user
private async Task<bool> LoginUser()
{
var result = IdentityRepository.LoginUser(User);
await result;
if (!result.Result.Item1)
{
LoginMessage = result.Result.Item2.ToString();
return false;
}
var token = result.Result.Item2 as SignInResponseDto;
await LocalStorage.SetItemAsync("token", token.Token);
await AuthStateProvider.GetAuthenticationStateAsync();
TokenStore.Jwt = token.Token; // Inject the TokenStore as Service and then change the value
// Now you can make requests with HttpClient to GraphQL server with the changed value
NavigationManager.NavigateTo("/");
return await Task.FromResult(true);
}
@danny-zegel-zocdoc Your solution proposal 2 is the best IMO
@Lukeuke I'm facing exactly the same issue, but I think your solution will still only have one CryptoClient with the first JWT you set and then that one will be reused by all subsequent requests?
We're facing a similar problem. In our case, the token is user-specific and can only be provided from a scoped context. I've read many issues similar to this one and have yet to find a workaround.
I believe I saw a reference that things were being redone to address this in version 14, but I don't know when that will be and I'm not sure it will fix my scenario.
I didn't think our use-case was unusual. We have an application with multiple tenants and we don't want customers in one accessing data from another. Anyone have a workaround to suggest?
@mikeries You can check this https://github.com/ChilliCream/graphql-platform/issues/3467#issuecomment-1962226640
Thanks! That worked great!
On Thu, Apr 4, 2024 at 1:19 PM Socolin @.***> wrote:
@mikeries https://github.com/mikeries You can check this #3467 (comment) https://github.com/ChilliCream/graphql-platform/issues/3467#issuecomment-1962226640
— Reply to this email directly, view it on GitHub https://github.com/ChilliCream/graphql-platform/issues/6426#issuecomment-2037887800, or unsubscribe https://github.com/notifications/unsubscribe-auth/AECETTRMFPFSPJIPALOJ7TDY3WKRXAVCNFSM6AAAAAA3KLZGBGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMZXHA4DOOBQGA . You are receiving this because you were mentioned.Message ID: @.***>
@Lukeuke I'm facing exactly the same issue, but I think your solution will still only have one CryptoClient with the first JWT you set and then that one will be reused by all subsequent requests?
If this is still relevant for you: I can confirm that the client is getting regenerated for every request. To quote the documentation:
Strawberry Shake uses the HttpClientFactory to generate a HttpClient on every request.
Product
Strawberry Shake
Is your feature request related to a problem?
I've been following the docs: chillicream.com/docs/strawberryshake/v13/get-started and I ran into an issue, because there's nowhere I can add request headers to the Query.
I have configured client in
Program.cs
And I have this simple Query that I want to execute:
I'm executing it like this:
But the endpoint that I'm hitting is
Authorized
:I've been searching the docs but the only solution that I found is that I can do it like this:
But the thing is that my token is dynamic and its from the LocalStorage so I can't just assign it to the Program.cs
The solution you'd like
I would like to have access to something like: