After adding authentication to our backend Graphql server the "Schema" and "Docs" are no longer visible in the Graphql Playground. Executing queries when adding a token to the "HTTP HEADERS" in the Playground does work correctly when authenticated and not when a user isn't authenticated, so that's ok.
We disabled the built-in Playground from Apollo-server and used the middleware graphql-playground-middleware-express
to be able to use a different URL and bypass authentication. We can now browse to the Playground and use it but we can't read the "Schema" or "Docs" there.
Trying to enable introspection
didn't fix this. Would it be better to call passport.authenticate()
in the Context
of apollo-server
? There's also a tool called passport-graphql but it works with local strategy and might not solve the problem. I've also tried setting the token in the header before calling the Playground route, but that didn't work.
We're a bit lost at this. Thank you for any insights you could give us.
The relevant code:
// index/ts
import passport from 'passport'
import expressPlayground from 'graphql-playground-middleware-express'
const app = express()
app.use(cors({ origin: true }))
app.get('/playground', expressPlayground({ endpoint: '/graphql' }))
app.use(passport.initialize())
passport.use(bearerStrategy)
app.use(
passport.authenticate('oauth-bearer', { session: false }),
(req, _res, next) => { next() }
)
;(async () => {
await createConnections()
const server = await new ApolloServer({
schema: await getSchema(),
context: ({ req }) => ({ getUser: () => req.user, }),
introspection: false,
playground: false,
})
server.applyMiddleware({ app, cors: false })
app.listen({ port: ENVIRONMENT.port }, () => { console.log(`Server ready`) })
})()
// passport.ts
import { IBearerStrategyOptionWithRequest, BearerStrategy, ITokenPayload } from passport-azure-ad'
import { Account } from '@it-portal/entity/Account'
export const bearerStrategy = new BearerStrategy( config,
async (token: ITokenPayload, done: CallableFunction) => {
try {
if (!token.oid) throw 'token oid missing'
const knownAccount = await Account.findOne({ accountIdentifier: token.oid })
if (knownAccount) return done(null, knownAccount, token)
const account = new Account()
account.accountIdentifier = token.oid
account.name = token.name
account.userName = (token as any).preferred_username
const newAccount = await account.save()
return done(null, newAccount, token)
} catch (error) {
console.error(`Failed adding the user to the request object: ${error}`)
}
}
)