Skip to content

Instantly share code, notes, and snippets.

@marcelovue
Last active April 18, 2019 18:00
Show Gist options
  • Save marcelovue/7451fe6aed04a87fdff3eec4d6be52ee to your computer and use it in GitHub Desktop.
Save marcelovue/7451fe6aed04a87fdff3eec4d6be52ee to your computer and use it in GitHub Desktop.
That's how I did PUBLIC and PRIVATE resolvers in my express apollo server, wondering if its the best way of doing it

I wanted to create a graphql apollo server without using a separate route like:

app.post('/login', () => {//do stuff})
app.post('/signup', () => {//do stuff})

So I decided to create an middleware to all my graphql resolvers, but I'm wondering if does exist a best way of doing it.

Of course I could verify the user by putting a verify function inside the context, but I don't want to make it, I think putting a new String in an array is more convenient

I'm using passport for the authentication and setting a custom property req.authenticated to know if the users is authenticated or not

export const protectResolvers = (resolvers) => {
let PUBLIC_RESOLVERS = ["login", "saveUser"]
let mutations = Object.assign({}, resolvers.Mutation)
let queries = Object.assign({}, resolvers.Query)
resolvers.Mutation = {}
resolvers.Query = {}
for (let name of Object.keys(mutations)) {
resolvers.Mutation[name] = async (...arguments1) => {
let req = arguments1[2].req
if (!req.authenticated) { //GO TO INDEX.JS AND U'LL SEE THE PASSPORT.AUTHENTICATE
if (PUBLIC_RESOLVERS.indexOf(name) < 0) { //PRIVATE ROUTES
throw new Error("You don't have permission to make this operation")
} else { //CALL ONLY PUBLIC MUTATIONS
return await mutations[name](...arguments1)
}
} else { //IF AUTHENTICATED, ANY ROUTE IS ACCESSIBLE
return await mutations[name](...arguments1)
}
}
}
for (let name of Object.keys(queries)) {
resolvers.Query[name] = async (...arguments1) => {
let req = arguments1[2].req
if (!req.authenticated) {
if (PUBLIC_RESOLVERS.indexOf(name) < 0) { //PRIVATE ROUTES
throw new Error("You don't have permission to make this operation")
} else { //CALL ONLY PUBLIC MUTATIONS
return await queries[name](...arguments1)
}
} else { //IF AUTHENTICATED, ANY ROUTE IS ACCESSIBLE
return await queries[name](...arguments1)
}
}
}
return resolvers
}
import resolvers from "./resolvers"
import { protectResolvers } from "./helpers"
resolvers = protectResolvers(resolvers)
//now u can use ur resolvers in the graphql
//lets pretend that we have the express setup here
app.use('/graphql', (req, res, next) => {
passport.authenticate('jwt', {session: false}, (err, user) => {
if (err) {
req.authenticated = false
} else if (user) {
req.authenticated = true
req.user = user
} else {
req.authenticated = false
}
next()
})(req,res,next)
})
export default const resolvers = {
Mutation: {
login: async (email, pass) => {
//...logic
},
saveUser: async (email, pass) => {
//...logic
},
// 'getAllUsers' is not in my ALLOWED_RESOLVERS, so it wont execute
getAllUsers: async (email, pass) => {
//...logic
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment