Authentication with GraphQL using @Guard
See original GitHub issueI’m submitting a…
[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Current behavior
The /graphql
route is accessible.
Expected behavior
The /graphql
should be not accessible.
Minimal reproduction of the problem with instructions
@Module({
imports: [GraphQLModule, AuthModule],
controllers: [AppController]
})
export class ApplicationModule implements NestModule {
constructor(private readonly graphQLFactory: GraphQLFactory) {}
configure(consumer: MiddlewaresConsumer) {
const typeDefs = this.graphQLFactory.mergeTypesByPaths('./**/*.graphql');
const schema = this.graphQLFactory.createSchema({ typeDefs });
consumer
.apply(graphiqlExpress({ endpointURL: '/graphql' }))
.forRoutes({ path: '/graphiql', method: RequestMethod.GET })
.apply(graphqlExpress(req => ({ schema, rootValue: req })))
.forRoutes({ path: '/graphql', method: RequestMethod.ALL });
}
}
@Module({
components: [AuthService, JwtStrategy],
controllers: [AuthController],
})
export class AuthModule implements NestModule {
public configure(consumer: MiddlewaresConsumer) {
consumer
.apply(passport.authenticate('jwt', { session: false }))
.forRoutes({ path: '/graphql', method: RequestMethod.ALL });
}
}
What is the motivation / use case for changing the behavior?
Environment
Nest version: 4.5.10
For Tooling issues:
- Node version: 9.4.0
- Platform: Mac
Others:
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:24 (5 by maintainers)
Top Results From Across the Web
Authentication and authorization - Apollo GraphQL Docs
Control access to your GraphQL API. ... Authentication is determining whether a given user is logged in, and subsequently determining which user someone...
Read more >how to implement user guards in nestjs graphql - Stack Overflow
This is what I'm using for GraphqlJwtAuthGuard based on documentaion: @Injectable() export class GqlJwtAuthGuard extends AuthGuard('jwt') ...
Read more >Authentication and Authorization in GraphQL – The Guild
To add guards to your resolvers, you can use a simple Middleware approach, and wrap your resolver with a function that checks if...
Read more >Authentication - Lighthouse PHP
You can configure a default guard to use for authenticating GraphQL requests in lighthouse.php . 'guard' => 'api',. This setting is used whenever...
Read more >GraphQL Authentication and Authorization in Node.js
In today's article we are going to work with the user's permissions, first we will create the account, then we will go to...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
For me current implementation of nestjs/graphql has two problems.
it use
apollo-server-express
directly, so response is send directly from this middleware and connection is closed - it breaks nest flow.guards use
rootValue
asdataOrRequest
forcanActivate
, it’s hard to use if we would like to use guards on deeper level than root - I think that it should to use context from GraphQLhere is very simple example with some changes which try to resolve above problems: https://github.com/mchmielarski/nest-graphql-example
@mchmielarski Thanks for linking these issues!
I did it somewhat different but experience the same problem. Applying app.useGlobalGuards(aGuard) will not trigger that guard for calls to a graphql endpoint.
How I did authentication/authorisation: Instead of crearing a JwtStrategy object and putting it before the routes, inside a global guard called ClaimsGuard I capture all requests. In the guard, if controller endpoints or resolvers are annotated with @Unauthorised() I allow everything. If they are not, I look for a jwt token, verify it myself with the secret in my database and extract its payload. Its payload is an object of type BearerToken that contains claims.
I then match the claims that user has with the claims combined of controller/resolver level and controller/resolver endpoint.
src: https://github.com/elewa-company/elewa-lms/blob/master/elewa-backend/src/modules/auth/gaurds/claims.gaurd.ts
I set the strategy on where to get the token by simple inheritance
On server start, I then register the guard.
This strategy works for controller endpoints and the first line (console.log) of the guard is called at each controller endpoint. (I still need to test all use cases so might still contain some bugs)
My issue, and what I think is a bug, is that that console.log is not called when accessing graphql endpoints. So the guard is for some reason ignored.
More info in #434
P.S. My Graphql Endpoint configuration: