How do I implement auth directive for mutations with Apollo?
I am trying to set up an Apollo backend for a project I'm working on, where I'm attempting to implement schema directives. However, I am not able to add my schema directive to mutations. So to my main question: How do I implement an auth directive for mutations?
I have added @auth(requires: ADMIN)
to the end of my users query, which is working fine. Apollo will then require a bearer token with admin access for performing the users query.
extend type Query {
user(id: ID!): User
users: [User!]! @auth(requires: ADMIN)
}
When I tried to do it in the same way for the editMyUser mutation, the auth directive seems to be enforced for all the mutations, instead of just the one I wanted. Even the signUp mutation will give "not authorized" error, when I add the @auth part to the editMyUser mutation. Even though there is no relation between them.
The role field which is supposed to be passed to the auth directive when invoked is logging out empty.
extend type Mutation {
signUp(
username: String!
firstName: String
lastName: String
password: String!
isAdmin: Boolean
isActive: Boolean): User!
login(
username: String!
password: String!): User!
editMyUser(
id: ID!
firstName: String
lastName: String
password: String): User! @auth(requires: USER)
adminEditUser(
id: ID!
firstName: String
lastName: String
password: String
isActive: Boolean
isAdmin: Boolean
isBanned: Boolean): User!
}
This is how I implemented the schema directive
export default gql`
directive @auth(requires: Role = ADMIN) on OBJECT | FIELD_DEFINITION
enum Role {
ADMIN
USER
}
https://github.com/jwhenshaw/graphql-directives-auth
This is the Auth Directive I've implemented in my code for reference.
So to summarise, when I implement auth directives for mutations they are implemented for all mutations, instead of just the one, and it is not even working correctly, as roles are not passed on to the directive.
I would love to get some help with this. Thanks!
javascript authentication graphql apollo apollo-server
add a comment |
I am trying to set up an Apollo backend for a project I'm working on, where I'm attempting to implement schema directives. However, I am not able to add my schema directive to mutations. So to my main question: How do I implement an auth directive for mutations?
I have added @auth(requires: ADMIN)
to the end of my users query, which is working fine. Apollo will then require a bearer token with admin access for performing the users query.
extend type Query {
user(id: ID!): User
users: [User!]! @auth(requires: ADMIN)
}
When I tried to do it in the same way for the editMyUser mutation, the auth directive seems to be enforced for all the mutations, instead of just the one I wanted. Even the signUp mutation will give "not authorized" error, when I add the @auth part to the editMyUser mutation. Even though there is no relation between them.
The role field which is supposed to be passed to the auth directive when invoked is logging out empty.
extend type Mutation {
signUp(
username: String!
firstName: String
lastName: String
password: String!
isAdmin: Boolean
isActive: Boolean): User!
login(
username: String!
password: String!): User!
editMyUser(
id: ID!
firstName: String
lastName: String
password: String): User! @auth(requires: USER)
adminEditUser(
id: ID!
firstName: String
lastName: String
password: String
isActive: Boolean
isAdmin: Boolean
isBanned: Boolean): User!
}
This is how I implemented the schema directive
export default gql`
directive @auth(requires: Role = ADMIN) on OBJECT | FIELD_DEFINITION
enum Role {
ADMIN
USER
}
https://github.com/jwhenshaw/graphql-directives-auth
This is the Auth Directive I've implemented in my code for reference.
So to summarise, when I implement auth directives for mutations they are implemented for all mutations, instead of just the one, and it is not even working correctly, as roles are not passed on to the directive.
I would love to get some help with this. Thanks!
javascript authentication graphql apollo apollo-server
add a comment |
I am trying to set up an Apollo backend for a project I'm working on, where I'm attempting to implement schema directives. However, I am not able to add my schema directive to mutations. So to my main question: How do I implement an auth directive for mutations?
I have added @auth(requires: ADMIN)
to the end of my users query, which is working fine. Apollo will then require a bearer token with admin access for performing the users query.
extend type Query {
user(id: ID!): User
users: [User!]! @auth(requires: ADMIN)
}
When I tried to do it in the same way for the editMyUser mutation, the auth directive seems to be enforced for all the mutations, instead of just the one I wanted. Even the signUp mutation will give "not authorized" error, when I add the @auth part to the editMyUser mutation. Even though there is no relation between them.
The role field which is supposed to be passed to the auth directive when invoked is logging out empty.
extend type Mutation {
signUp(
username: String!
firstName: String
lastName: String
password: String!
isAdmin: Boolean
isActive: Boolean): User!
login(
username: String!
password: String!): User!
editMyUser(
id: ID!
firstName: String
lastName: String
password: String): User! @auth(requires: USER)
adminEditUser(
id: ID!
firstName: String
lastName: String
password: String
isActive: Boolean
isAdmin: Boolean
isBanned: Boolean): User!
}
This is how I implemented the schema directive
export default gql`
directive @auth(requires: Role = ADMIN) on OBJECT | FIELD_DEFINITION
enum Role {
ADMIN
USER
}
https://github.com/jwhenshaw/graphql-directives-auth
This is the Auth Directive I've implemented in my code for reference.
So to summarise, when I implement auth directives for mutations they are implemented for all mutations, instead of just the one, and it is not even working correctly, as roles are not passed on to the directive.
I would love to get some help with this. Thanks!
javascript authentication graphql apollo apollo-server
I am trying to set up an Apollo backend for a project I'm working on, where I'm attempting to implement schema directives. However, I am not able to add my schema directive to mutations. So to my main question: How do I implement an auth directive for mutations?
I have added @auth(requires: ADMIN)
to the end of my users query, which is working fine. Apollo will then require a bearer token with admin access for performing the users query.
extend type Query {
user(id: ID!): User
users: [User!]! @auth(requires: ADMIN)
}
When I tried to do it in the same way for the editMyUser mutation, the auth directive seems to be enforced for all the mutations, instead of just the one I wanted. Even the signUp mutation will give "not authorized" error, when I add the @auth part to the editMyUser mutation. Even though there is no relation between them.
The role field which is supposed to be passed to the auth directive when invoked is logging out empty.
extend type Mutation {
signUp(
username: String!
firstName: String
lastName: String
password: String!
isAdmin: Boolean
isActive: Boolean): User!
login(
username: String!
password: String!): User!
editMyUser(
id: ID!
firstName: String
lastName: String
password: String): User! @auth(requires: USER)
adminEditUser(
id: ID!
firstName: String
lastName: String
password: String
isActive: Boolean
isAdmin: Boolean
isBanned: Boolean): User!
}
This is how I implemented the schema directive
export default gql`
directive @auth(requires: Role = ADMIN) on OBJECT | FIELD_DEFINITION
enum Role {
ADMIN
USER
}
https://github.com/jwhenshaw/graphql-directives-auth
This is the Auth Directive I've implemented in my code for reference.
So to summarise, when I implement auth directives for mutations they are implemented for all mutations, instead of just the one, and it is not even working correctly, as roles are not passed on to the directive.
I would love to get some help with this. Thanks!
javascript authentication graphql apollo apollo-server
javascript authentication graphql apollo apollo-server
edited Jan 2 at 11:18
Ahmed Ashour
3,604102643
3,604102643
asked Jan 2 at 10:19
fantastiskfantastisk
207
207
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Within that repo the AuthDirective
class passes the objectType
of the field being wrapped into the ensureFieldWrapped
method. What this means is that for your example where you are assigning the directive directly onto a field, editMyUser
, on the object of Mutation
the method is wrapping all the children of Mutation
(I believe the same should be true for your Queries as well actually).
So, within the example repo, this is fine as we have an Object type User
and we wrap it and its fields. However, if you do not wish to do this we can alter the AuthDirective
class to wrap just the field it is on.
I have done this and pushed to the repo, https://github.com/jwhenshaw/graphql-directives-auth, where you can see there is now a FieldAuthDirective
and a ObjectAuthDirective
. I still need to clean the code a bit but pushed a working example and left some logs to help highlight the differences. You can view it here https://qzj70qn2mj.sse.codesandbox.io/ if you don't fancy running it locally.
Hope this helps, let me know if I need to elaborate some more.
add a comment |
The issue here is that the referenced implementation throws an error when the wrapping resolver does not find any required roles (neither for the object type nor the field in question) in these lines of code.
The logic is that as you use the directive for some field of an object type, you also need to provide a requirement for the type itself. In my opinion this logic isn't too bad and is as the code comment suggests to be on the safe side. The author of that implementation probably focused on usage of the directive for actual data types, not for queries or mutations.
Let me be even a little more specific: What you and I do (as I am trying to accomplish the same thing as you today), when using the directive for one or several queries/mutations is actually applying the directive on the fields of the schema types Query
and Mutation
. So if we don't want a minimum requirement for all queries and/or mutations of our schema, the code should not throw an error in that condition I linked above, but it should call the wrapped resolver just as if the requirements were met (because there are none).
Example:
if (!requiredRole) {
// No auth required, just call the resolver
return resolve.apply(this, args);
}
I hope this helps! 🙂
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54004551%2fhow-do-i-implement-auth-directive-for-mutations-with-apollo%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Within that repo the AuthDirective
class passes the objectType
of the field being wrapped into the ensureFieldWrapped
method. What this means is that for your example where you are assigning the directive directly onto a field, editMyUser
, on the object of Mutation
the method is wrapping all the children of Mutation
(I believe the same should be true for your Queries as well actually).
So, within the example repo, this is fine as we have an Object type User
and we wrap it and its fields. However, if you do not wish to do this we can alter the AuthDirective
class to wrap just the field it is on.
I have done this and pushed to the repo, https://github.com/jwhenshaw/graphql-directives-auth, where you can see there is now a FieldAuthDirective
and a ObjectAuthDirective
. I still need to clean the code a bit but pushed a working example and left some logs to help highlight the differences. You can view it here https://qzj70qn2mj.sse.codesandbox.io/ if you don't fancy running it locally.
Hope this helps, let me know if I need to elaborate some more.
add a comment |
Within that repo the AuthDirective
class passes the objectType
of the field being wrapped into the ensureFieldWrapped
method. What this means is that for your example where you are assigning the directive directly onto a field, editMyUser
, on the object of Mutation
the method is wrapping all the children of Mutation
(I believe the same should be true for your Queries as well actually).
So, within the example repo, this is fine as we have an Object type User
and we wrap it and its fields. However, if you do not wish to do this we can alter the AuthDirective
class to wrap just the field it is on.
I have done this and pushed to the repo, https://github.com/jwhenshaw/graphql-directives-auth, where you can see there is now a FieldAuthDirective
and a ObjectAuthDirective
. I still need to clean the code a bit but pushed a working example and left some logs to help highlight the differences. You can view it here https://qzj70qn2mj.sse.codesandbox.io/ if you don't fancy running it locally.
Hope this helps, let me know if I need to elaborate some more.
add a comment |
Within that repo the AuthDirective
class passes the objectType
of the field being wrapped into the ensureFieldWrapped
method. What this means is that for your example where you are assigning the directive directly onto a field, editMyUser
, on the object of Mutation
the method is wrapping all the children of Mutation
(I believe the same should be true for your Queries as well actually).
So, within the example repo, this is fine as we have an Object type User
and we wrap it and its fields. However, if you do not wish to do this we can alter the AuthDirective
class to wrap just the field it is on.
I have done this and pushed to the repo, https://github.com/jwhenshaw/graphql-directives-auth, where you can see there is now a FieldAuthDirective
and a ObjectAuthDirective
. I still need to clean the code a bit but pushed a working example and left some logs to help highlight the differences. You can view it here https://qzj70qn2mj.sse.codesandbox.io/ if you don't fancy running it locally.
Hope this helps, let me know if I need to elaborate some more.
Within that repo the AuthDirective
class passes the objectType
of the field being wrapped into the ensureFieldWrapped
method. What this means is that for your example where you are assigning the directive directly onto a field, editMyUser
, on the object of Mutation
the method is wrapping all the children of Mutation
(I believe the same should be true for your Queries as well actually).
So, within the example repo, this is fine as we have an Object type User
and we wrap it and its fields. However, if you do not wish to do this we can alter the AuthDirective
class to wrap just the field it is on.
I have done this and pushed to the repo, https://github.com/jwhenshaw/graphql-directives-auth, where you can see there is now a FieldAuthDirective
and a ObjectAuthDirective
. I still need to clean the code a bit but pushed a working example and left some logs to help highlight the differences. You can view it here https://qzj70qn2mj.sse.codesandbox.io/ if you don't fancy running it locally.
Hope this helps, let me know if I need to elaborate some more.
answered Jan 2 at 16:22
James HenshawJames Henshaw
361
361
add a comment |
add a comment |
The issue here is that the referenced implementation throws an error when the wrapping resolver does not find any required roles (neither for the object type nor the field in question) in these lines of code.
The logic is that as you use the directive for some field of an object type, you also need to provide a requirement for the type itself. In my opinion this logic isn't too bad and is as the code comment suggests to be on the safe side. The author of that implementation probably focused on usage of the directive for actual data types, not for queries or mutations.
Let me be even a little more specific: What you and I do (as I am trying to accomplish the same thing as you today), when using the directive for one or several queries/mutations is actually applying the directive on the fields of the schema types Query
and Mutation
. So if we don't want a minimum requirement for all queries and/or mutations of our schema, the code should not throw an error in that condition I linked above, but it should call the wrapped resolver just as if the requirements were met (because there are none).
Example:
if (!requiredRole) {
// No auth required, just call the resolver
return resolve.apply(this, args);
}
I hope this helps! 🙂
add a comment |
The issue here is that the referenced implementation throws an error when the wrapping resolver does not find any required roles (neither for the object type nor the field in question) in these lines of code.
The logic is that as you use the directive for some field of an object type, you also need to provide a requirement for the type itself. In my opinion this logic isn't too bad and is as the code comment suggests to be on the safe side. The author of that implementation probably focused on usage of the directive for actual data types, not for queries or mutations.
Let me be even a little more specific: What you and I do (as I am trying to accomplish the same thing as you today), when using the directive for one or several queries/mutations is actually applying the directive on the fields of the schema types Query
and Mutation
. So if we don't want a minimum requirement for all queries and/or mutations of our schema, the code should not throw an error in that condition I linked above, but it should call the wrapped resolver just as if the requirements were met (because there are none).
Example:
if (!requiredRole) {
// No auth required, just call the resolver
return resolve.apply(this, args);
}
I hope this helps! 🙂
add a comment |
The issue here is that the referenced implementation throws an error when the wrapping resolver does not find any required roles (neither for the object type nor the field in question) in these lines of code.
The logic is that as you use the directive for some field of an object type, you also need to provide a requirement for the type itself. In my opinion this logic isn't too bad and is as the code comment suggests to be on the safe side. The author of that implementation probably focused on usage of the directive for actual data types, not for queries or mutations.
Let me be even a little more specific: What you and I do (as I am trying to accomplish the same thing as you today), when using the directive for one or several queries/mutations is actually applying the directive on the fields of the schema types Query
and Mutation
. So if we don't want a minimum requirement for all queries and/or mutations of our schema, the code should not throw an error in that condition I linked above, but it should call the wrapped resolver just as if the requirements were met (because there are none).
Example:
if (!requiredRole) {
// No auth required, just call the resolver
return resolve.apply(this, args);
}
I hope this helps! 🙂
The issue here is that the referenced implementation throws an error when the wrapping resolver does not find any required roles (neither for the object type nor the field in question) in these lines of code.
The logic is that as you use the directive for some field of an object type, you also need to provide a requirement for the type itself. In my opinion this logic isn't too bad and is as the code comment suggests to be on the safe side. The author of that implementation probably focused on usage of the directive for actual data types, not for queries or mutations.
Let me be even a little more specific: What you and I do (as I am trying to accomplish the same thing as you today), when using the directive for one or several queries/mutations is actually applying the directive on the fields of the schema types Query
and Mutation
. So if we don't want a minimum requirement for all queries and/or mutations of our schema, the code should not throw an error in that condition I linked above, but it should call the wrapped resolver just as if the requirements were met (because there are none).
Example:
if (!requiredRole) {
// No auth required, just call the resolver
return resolve.apply(this, args);
}
I hope this helps! 🙂
answered Jan 2 at 16:21
nether_catnether_cat
11616
11616
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54004551%2fhow-do-i-implement-auth-directive-for-mutations-with-apollo%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown