Closed sulliwane closed 4 years ago
@khaledosman - thank you for your input. Would you mind help me understand it in some more detail? Are you looking for an explicit method for setting the HTTP headers? At this point I believe you can do something like this:
// This is where you can choose what auth headers to add
function headerGenerator() {
return {
'Authorization': 'Bearer <your token goes here>',
}
}
// Semi generic GraphQL query execution method
function graphQLFetcher(additionalHeadersFunction) {
return function(graphQLParams) {
return fetch('/graphql', {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
...additionalHeadersFunction()
},
body: JSON.stringify(graphQLParams),
credentials: 'include',
}).then(function(response) {
return JSON.parse(response.text());
});
}
}
ReactDOM.render(
React.createElement(GraphiQL, {
fetcher: graphQLFetcher(headerGenerator),
}),
document.getElementById('graphiql')
);
This level of effort appears relatively low to me. Would you mind elaborating what you would like to see? Am I missing anything that this solution fundamentally does not deliver? Would you like to see this as a setup in the example package of the repo?
@Neitsch a setup example/readme would be a good start.
I think most people use the graphiql middleware and don't setup/use the react component manually, so I'd expect to bypass the component configuration all together and have some form for the headers rendered as part of the component or hidden behind a button that takes care of this by default.
@khaledosman - ah, apologies if I missed that before. That sounds pretty reasonable, especially small setups don't want to go through the trouble of setting all that up. I briefly looked into this. The key challenge is that express-graphql
basically only gives you server side configuration options. There are a few things we could attempt:
express-graphql
and make it work for your case. I would anticipate that it's pretty low effort, but it's a headache to maintain.Neither solution is particularly good, but that's the only two I can come up with right now. I'll keep thinking about it some more. Thanks again for the input!
For some inspiration this is how prisma's playground does it which is built on top of graphiql afaik. I can just enter a JSON object in the headers field which gets sent to the server. The new Apollo Server v2 now includes playground by default instead of graphiql.
My /graphql route is protected by JWT token, so every HTTP request needs to set:
headers: { Authorization: 'Bearer ' + token }
To get through the authentication middleware and hit /graphql.
How to manage this authentication step when using graphiql ? graphiql is so convenient, it's a pity to not use it :( thanks for any suggestion!
Currently we are using Modify Headers add ons to pass the token in our graphql
Just specify that header when creating your required fetcher!
For firefox users, here is the Modify Header Value
addon: https://addons.mozilla.org/en-US/firefox/addon/modify-header-value/?src=search
I definitely think it's easier to use something like mod header to solve this problem. It's avaiable in chrome or firefox
we will be providing an example soon, but all of this is possible with the current GraphiQL
@acao is this via the plugin system (in v1.0.0-alpha?) previously mentioned by @benjie ?
In GraphiQL v1 we're planning to add a plugin system
the plugin system will make it easier to provide a nice UI for this. there are going to be quite a few more alpha versions before we have a plugin system
this is all possible currently though, in 0.7.5 or the alpha, so i had hoped to provide a full auth example before I got too deep into working on monaco or the react refactor for plugins
I found a way to fix this problem. On Chrome, you can install an extention
ModHeader
https://chrome.google.com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj which will allow you to modify request or response headers. In this way, you can send Authorization header with each request and graphiql will work fine.
how to use it? please guide me
I used this chrome extentions thata allows to send headers https://chrome.google.com/webstore/detail/altair-graphql-client/flnheeellpciglgpaodhkhmapeljopja
This one works for me :)
I've decided - given that we are doing one final 1.0.0 (pre rewrite/plugins) stable release for GraphiQL, we get to have one feature.
And that's a headers tab. Whoever wants to, feel free to add a single tab for headers in a PR, and if we can get it merged next week, we can at least have that until we have a stable beta plugin API!
I've opened a draft PR for this :) #1543
As header tab is added to GraphiQL now we can close this issue right @acao?
Yep, if you upgrade to 1.0.0 you can enable the headers editor :D I have it enabled on my app here.
The code I use to create the GraphiQL instance with the headers editor enabled and pre-filled is this:
let graphQLFetcher = (graphQLParams, opts = { headers: {} }) => {
return fetch(window.location.origin + '/graphql', {
method: 'post',
headers: Object.assign({ 'Content-Type': 'application/json', 'User-Agent': 'vglist.co GraphiQL' }, opts.headers),
body: JSON.stringify(graphQLParams),
}).then(response => response.json());
}
ReactDOM.render(
React.createElement(GraphiQL, {
fetcher: graphQLFetcher,
headerEditorEnabled: true,
headers: '{\n "X-User-Email": "foo@example.com",\n "X-User-Token": "API_TOKEN_HERE"\n}'
}),
document.getElementById("graphiql-injection-point")
);
We should probably update the README to mention give a code example for using the headers editor and sending headers with the GraphiQL requests.
@connorshea excellent point, yes.
possibly we can add custom headers to the graphiql cdn exmaple?
The headerEditorEnabled
is great :-). Is there also some way to include those headers when graphiql asks for the schema? It seems like graphQLFetcher
is also used for fetching the schema but in that case opts
have empty headers (at least from my limited testing).
I'm deep into 2.0.0 plugin API now, but possibly @connorshea can add that for another 1.0.0 release? I should have caught that in the review, my bad.
to confirm, @jonaskello it was not added. i will pivot to fix this issue!
released #1593 as graphiql@1.03
, enjoy!
š @acao I think we can close this now :)
@acao I can confirm it works! Thanks :-)
thanks everyone!
for the record, and you can see this in the GraphiQL readme now, you can enable the headers editor with headersEditorEnabled
prop, and even use a static headers
string prop to set the default headers in the headers editor, and users can override this per-request in the headers tab.
thanks @connorshea for your work and @harshithpabbati and @ncthbrt for helping to review!
any new features for this will be part of graphiql@2.0.0
plugins, as, following the Spec WG, HTTP-driven functionality is now part of a seperate GraphQL HTTP Spec. We must honor the HTTP agnostic default spec by default, and then will have http plugins to follow the HTTP spec.
consider this a bonus for the very long feature freeze as we had to spend so long preparing GraphiQL for the rewrite, performing the rewrite, and are now working on the plugin spec. the new SDK-oriented approach will be very rewarding!
to add, if there are any more bugs with this new feature, we will gladly introduce them to 1.0.x patches :)
for the record, and you can see this in the GraphiQL readme now,
@acao I'm not seeing this in the readme. Would you possibly mind sharing a link to docs on how to use this feature?
for the record, and you can see this in the GraphiQL readme now, you can enable the headers editor with
headersEditorEnabled
prop
@acao you may want to edit this to save people time trying to figure out why it doesn't work - it's headerEditorEnabled
not headersEditorEnabled
(edit - shameless plug - I just made this, feedback welcomed https://github.com/penx/graphiql-middleware )
@penx thanks for the catch, will update!
your middleware looks great but it exposes a huge template injection attack surface - exposing xss and other potential attack vectors! i had to issue a CVE for graphql playground and issue a security fix for the same exact reasons. playground repo now has an example with a readme that explains all of this
we will be rolling our own middeware packages soon when i have time to get to it. there is still an open PR that needs cleanup if you want to create a new PR based off that to help advance that! We actually use ReactDOM/server in that PR there, but an xss filtered template tag implementation ala the new playground fix would be welcome as well. you can introduce several new typescript packages if you want, or just a basic underling renderer method like playground-html
Easy implementation to get JWT Token support in GraphiQL
https://gist.github.com/sasso/3c3d728e0049d5b66a2c19b349b7f164
This worked great, except the graphiql screen falls off the bottom of the page.
Here's a version using flexbox that aligns it properly: https://gist.github.com/craigmit/44499818664fc34083f2aa96069f0636
You could also use the headers editor:
Thanks @benjie
I didn't see that Request Headers
were now available.
I modified the new GraphiQL html, to automatically set the auth header from a # param (so you can call it directly from your application, automatically setting the Authorization header):
https://gist.github.com/craigmit/0cce78ffe33ca3551fbcc35016e8b3e2
Usage is:
graphiqlSetAuth.html#[JWT_TOKEN]
and it will set the Authorization header for you.
The only change to the original graphiql html was the addition of:
const tokenParam = window.location.hash.substr(1);
if (tokenParam) {
headers = {"Authorization": "Bearer " + tokenParam}
window.history.replaceState({}, document.title, window.location.href.split('#')[0]);
}
The request headers box works a treat!
const editor = (<GraphiQL headerEditorEnabled={true} fetcher={graphQLFetcher} />);
ReactDOM.render(editor, document.getElementById('graphiql-app'));
However, you must pass the headers through in your fetcher.
For example:
const graphQLFetcher = async (graphQLParams, opts) => {
const { headers = {} } = opts;
const response = await fetch('/graphql', {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
...headers,
},
body: JSON.stringify(graphQLParams),
});
return response.json();
};
Add Authentication in the UI itself
@m-thirumal hello, i try to configure api platform with jwt and graphql but I canāt do itā¦ all the time I have 403 when I use security grantedā¦
can you explain how have you configure security.yaml (and other file maybe) to make work pls š ?
graphqlHTTP({
schema,
rootValue,
graphiql: {
headerEditorEnabled: true
}
})
I have been digging through this thread trying to find a way to pass a header, the authorization header, to Graphiql in the request. I am running Graphiql in an iFrame from localhost:8000/graphql
and I want to be able to do something like localhost:8000/graphql?headers=serializedheadersstring
and have the header values be populated into the editor for all tabs.
Is this possible?
I have been digging through this thread trying to find a way to pass a header, the authorization header, to Graphiql in the request. I am running Graphiql in an iFrame from
localhost:8000/graphql
and I want to be able to do something likelocalhost:8000/graphql?headers=serializedheadersstring
and have the header values be populated into the editor for all tabs.Is this possible?
Not a solution but a work-around. You can run a local proxy that puts the GraphiQL UI and the GraphQL endpoint on the same port then the headers are shared automatically.
You can inject the following code snippet to make GraphiQL IDE work with Firebase Auth (ID token):
<script type="module">
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-app.js";
import { getAuth } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-auth.js";
const app = initializeApp({
projectId: "example",
appId: "xxxxx",
apiKey: "xxxxx",
authDomain: "example.com"
});
function setAuthHeader(token) {
const editor = document.querySelectorAll('.variable-editor .CodeMirror')[1].CodeMirror;
const headers = JSON.parse(editor.getValue());
headers.Authorization = token ? "Bearer " + token : undefined;
editor.setValue(JSON.stringify(headers, null, 2));
}
getAuth(app).onAuthStateChanged((user) => {
if (user) {
user.getIdToken().then(token => setAuthHeader(token));
} else {
setAuthHeader(null);
}
});
</script>
https://www.codementor.io/@koistya/graphiql-with-firebase-auth-251hx5qhz3
My /graphql route is protected by JWT token, so every HTTP request needs to set:
To get through the authentication middleware and hit /graphql.
How to manage this authentication step when using graphiql ? graphiql is so convenient, it's a pity to not use it :( thanks for any suggestion!