I have a backend API along with my single page app that will run queries and mutations to my database. Ideally, the @auth directives I’ve setup on my types should only apply to queries that come from my frontend. The backend should have unrestriced access to run any kinds of queries or mutations on the database.
I’ve tried doing it with the Dg-Auth header along with a client API key on Slash GraphQL and sending requests using this from my backend but that doesnt seem to work. Are there any docs or guidance along doing this?
To provide some more perspective, I come from a Firestore background where I did something similar. The Firestore auth rules apply to only queries coming from the firebase client running on users’ browsers. I would also have a REST API endpoint where I would be running firebase admin which would bypass the auth rules that are imposed on the client. Looking to do something similar here
When you say backend, are you talking about lamdas? I got backlash for pointing out that there should be no need for @auth directive when calling the query / mutation on a lambda. That query itself should be secured by you before it is run.
This would be a breaking change (even though it makes more sense), so I have not yet seen any support for this by my request.
However, you can run DQL on the backend (you have to learn it) without @auth directive necessity. In a week or so, it will also support JSON Mutations…
But to answer your question, a backend should never need @auth rules. However you are calling that backend should (or be secure). At least in all standard software products…
@jdgamble555 By backend I mean a separate NodeJS environment running an Express server, not running on DGraph Lambda
It is secured in that it is a trusted environment that will only run queries that I’ve programmed in there on a specific route and is authenticated in that every request made to it goes through an auth middleware that makes sure only authorized users are trying and allowed to do what the particular endpoint logic is programmed to do.
@jdgamble555 Essentially, what I’m asking is, is there a way to run queries and mutations on my database bypassing the @auth rules specified on the types?
Isn’t the client/admin API keys supposed to do that on Slash GraphQL? Is so, what’s the right way? Any documentation I can refer?
But for more direct control of changes, you would create your own custom mutation through lamdas, which do give you direct access to DQL without @auth rules…
This is my understanding, again, there may be another way I missed in the docs.
Note: Really, the easiest way would be to create an ADMIN role in your @auth directives. That way you can call it however you want. That really depends on your authorization api…
Chain multiple rules in your auth directive, e.g.:
@auth(
query: {
or: [
# Admins can see all users
{ rule: "{$ROLE: { eq: \"ADMIN\" }}" }
# users can see only their own data
{
rule: "query($USERNAME: String!) { queryOwnable{owner(filter: { username: {eq: $USERNAME }}) { username }}}"
}
]
}
So, here Firebase auth generates short lived 1 hour access token JWTs that Dgraph verifies using the auth mechanism specified. However, for the backend server, I dont see a straightforward way for the server to generate its own ADMIN role JWT tokens.
I’ll wait to see if the team has any other suggestions where I dont have to do the heavy lifting myself in terms of generating custom tokens and maintaining them. And also sprinkling that extra line of checking if role equals admin on all the auth directives seems boilerplatey.
I would love if what @chewxy suggested would work where I could just generate an admin token on Slash and that bypasses the auth roles completely
1.) There are other use cases (in lambdas) for bypassing @auth directive on the server end when calling graphql. I again, submit this as a feature request. Of course it needs to be optional to not break the code when @auth is needed.
2.) There still should be a way to call DQL directly, bypassing @auth, so you might want to mess with that.
3.) There may also be a way with an ADMIN token to do this, SOMEONE FROM DGRAPH PLEASE COMMENT HERE so that we can see how it is done.
4.) As far as Firebase, you can easily use the ADMIN SDK to create a custom token. Of course, you need a user. You would just pick the uid of a user with the ADMIN role:
admin
.auth()
.createCustomToken(uid)
Of course, that assumes the user already has the custom claim. If you add the custom claim on user.onCreate, then it should already be there. See my repo:
I’m facing the same issue right now and the workaround I’m implementing is the following:
Create an admin user in Firebase auth (just a normal user)
Retrieve that user’s ID
When initializing the Apollo client, first use the createCustomToken method from admin passing that user ID and adding the ADMIN claim or whatever claim you want to use