No result data when implmenting the auth directive

Hi, I am playing with the auth directive, but I don’t get it working. It appears to be all ok, I don’t have any errors, but I also don’t get any data back, so something must be wrong with my token.

My token looks like this when parsed:

{"dgraph_claims":{"USER":"John","ROLE":"admin","IS_AUTHENTICATED":true},"exp":1615692282}

My schema looks like this.

type Author @secret(field: "pwd") @auth(
   query:  { rule:  "{$IS_AUTHENTICATED: { eq: \"true\" } }"},
   add: { rule:  "{$ROLE: { eq: \"admin\" } }"},
   update: { rule:  "{$ROLE: { eq: \"admin\" } }"},
   delete: { rule:  "{$ROLE: { eq: \"admin\" } }"}
) {
	name: String! @id @search(by: [hash])
  role: String! @search(by: [hash])
}

type Post @auth(
  query: { rule:  "{$IS_AUTHENTICATED: { eq: \"true\" } }"},
  add: { rule:  "{$IS_AUTHENTICATED: { eq: \"true\" } }"},
  update: {
    or: [
      { rule:  "{$ROLE: { eq: \"admin\" } }"},
      { rule: "query ($USER: String!) { queryPost { author(filter: { name: { eq: $USER } }  ) { name } } }" }
    ]
  },
  delete: {
    or: [
      { rule:  "{$ROLE: { eq: \"admin\" } }"},
      { rule: "query ($USER: String!) { queryPost { author(filter: { name: { eq: $USER } }  ) { name } } }" }
    ]
  }
) {
  title: String! @id @search(by: [hash])
  author: Author!
  text: String!
}

# Dgraph.Authorization {"VerificationKey":"some_symmetric_key","Header":"X-App-Token","Namespace":"dgraph_claims","Algo":"HS256", "ClosedByDefault": true}

I am able to verify that my token generally works as the graph complains when it expires. So I know it was able to read it and at least know its not expired yet. But any rules I use based on the properties in the graph key don’t work.

Here I show how I add some sample data.

{
    set {
            _:john <dgraph.type> "Author" .
            _:john <Author.name> "John" .
            _:john <Author.pwd> "topsecret" .
            _:john <Author.role> "admin" .
            _:p <dgraph.type> "Post" .
            _:p <Post.author> _:john .
            _:p <Post.text> "Hello, world!"  .
}

I am sending the token from graphiql frontend.

function graphQLFetcher(graphQLParams) {
  return fetch(
    'http://localhost:8080/graphql',
    {
      method: 'post',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
        'X-App-Token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkZ3JhcGhfY2xhaW1zIjp7IlVTRVIiOiJKb2huIiwiUk9MRSI6ImFkbWluIiwiSVNfQVVUSEVOVElDQVRFRCI6dHJ1ZX0sImV4cCI6MTYxNTY5MjI4Mn0.vdXRssyRzsiUc2y4AxmXDzChAVy5YjFFexISeUseeSw'
      },
      body: JSON.stringify(graphQLParams),
      credentials: 'omit',
    },
  ).then(function (response) {
    return response.json().catch(function () {
      return response.text();
    });
  });
}

General token validation is working at this point, but query does not show me any author or post.

I know the data is there because I can see it with ratel

I know the token validation itself is working because when I let it expire I get this

{
  "errors": [
    {
      "message": "couldn't rewrite query queryPost because unable to parse jwt token:token is expired by 7m18.072700757s"
    }
  ],
  "data": {
    "queryPost": []
  },
  ...
}

If anyone knows where I am going wrong, I would be glad for some help.

In your JWT you are setting IS_AUTHENTICATED as a Boolean, but in your auth rule, you you are comparing it against a string. A boolean will never equal a string in this syntax.

Real Boolean types were only very recently supported by Dgraph RBAC auth rules. You may need to use a string in your JWT and leave the rule as is depending on your version.

You are right. Thanks for pointing this out. I have used the rule from the official docs. -maybe a hint there would be good.

Apart from that I could have sworn that it even didn’t work when I only had 1 rule in place ad first to compare against the username. I have created such a rule again, and it worked too.

Thanks so much again :slight_smile:

One side question, when I set "ClosedByDefault": true in the schema, is this not kind of the same as checking for some boolean? Since usually we would only hand out a token to an authenticated user in the first place.

Correct.

1 Like