{"id":16927443,"url":"https://github.com/martinemde/graphql-node-auth-example","last_synced_at":"2026-04-16T12:04:26.071Z","repository":{"id":66953878,"uuid":"385390561","full_name":"martinemde/graphql-node-auth-example","owner":"martinemde","description":"An example Express GraphQL API that uses Auth0 to authenticate queries ","archived":false,"fork":false,"pushed_at":"2021-07-15T01:28:56.000Z","size":16,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-14T20:37:16.803Z","etag":null,"topics":["authentication","example","express","graphql","jwt"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/martinemde.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-12T21:41:25.000Z","updated_at":"2022-04-25T18:02:56.000Z","dependencies_parsed_at":"2023-05-15T19:15:25.966Z","dependency_job_id":null,"html_url":"https://github.com/martinemde/graphql-node-auth-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/martinemde/graphql-node-auth-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinemde%2Fgraphql-node-auth-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinemde%2Fgraphql-node-auth-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinemde%2Fgraphql-node-auth-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinemde%2Fgraphql-node-auth-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/martinemde","download_url":"https://codeload.github.com/martinemde/graphql-node-auth-example/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinemde%2Fgraphql-node-auth-example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31884931,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T11:36:10.202Z","status":"ssl_error","status_checked_at":"2026-04-16T11:36:09.652Z","response_time":69,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","example","express","graphql","jwt"],"created_at":"2024-10-13T20:34:15.038Z","updated_at":"2026-04-16T12:04:26.054Z","avatar_url":"https://github.com/martinemde.png","language":"JavaScript","readme":"# graphql-node-auth-example\n\nAn example app that uses Auth0 to authenticate an Express GraphQL app\n\nThe purpose of this app is to show how to make a secure authentication system for GraphQL without using graphql mutations for login and signup.\n\nI believe using graphql for signup and login mutations causes more harm than good. Read more about my opinion on the Cloud City Development blog.\n\n# Principals of good out-of-band authentication in GraphQL\n\n- Use a separate authentication endpoint\n- Require authentication for the entire GraphQL endpoint\n- Return 401 on failed or expired authentication\n- Load the user into context before executing the query\n\nI built this app with the aim of explaining these principals so other's could build from an example that starts with good practices. My hope is to save you from security vulnerabilities and ultimately reduce the pain of a future migration to a better authentication system. Ultimately, every application is unique, and though I tried to give a good example, this is still just a toy app I made to explain these ideas. It's up to you to evaluate my code and make your own decisions about your security practices. I hope my example gives you another perspective that makes your application better and more secure.\n\n## Getting Started\n\nIf you'd like to run this test app, first, follow the [Auth0 Node tutorial](https://auth0.com/docs/quickstart/backend/nodejs/01-authorization) until you have an API configured in Auth0. You don't need to setup permissions or create an application on Auth0. I don't use any of that here.\n\nClone the app locally and install dependencies\n\n```\nnpm i\n```\n\nModify `config.js` to use your freshly configured Auth0 values for your domain and audience.\n\nRun the server\n\n```\nnpm start\n```\n\nFetch your example API token using the test token cURL command from the Auth0 dashboard.\n\nTo find this test API token command, go to the [API section on the Auth0 Dashboard](https://manage.auth0.com/dashboard/us/dev-cc-example/apis) and click on the API you created in the Tutorial I linked above. Choose the 'Test' submenu and copy the cURL commannd. It should look something like the command below:\n\n(this command will change depending on your Auth0 config, don't copy my command here).\n\n```\n# Don't copy this, get your own!\ncurl --request POST \\\n  --url https://dev-cc-example.us.auth0.com/oauth/token \\\n  --header 'content-type: application/json' \\\n  --data '{\"client_id\":\"jMGqRLbIMYf9UQhZs6i5f9mgkiZpD0Yt\",\"client_secret\":\"930200nall1cPWV-FLs8hu20934b-RzBzluhhha383hoheOEli0dJ73CvFIJXl20\",\"audience\":\"https://graphqlauth.example/graphql\",\"grant_type\":\"client_credentials\"}'\n```\n\nYou'll get a response like the following which contains your new auth token.\n\n```\n{\"access_token\":\"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkF3ZFVIcWNoUUw5NENoeGxZSDBzRSJ9.eyJpc3MiOiJodHRwczovL2Rldi1jYy1leGFtcGxlLnVzLmF1dGgwLmNvbS8iLCJzdWIiOiJqTUdxUkxiSU1ZZjlVUWhaczZpNWY5bWdraVpwRDBZdEBjbGllbnRzIiwiYXVkIjoiaHR0cHM6Ly9ncmFwaHFsYXV0aC5leGFtcGxlL2dyYXBocWwiLCJpYXQiOjE2MjYxMjU4MzksImV4cCI6MTYyNjIxMjIzOSwiYXpwIjoiak1HcVJMYklNWWY5VVFoWnM2aTVmOW1na2lacEQwWXQiLCJndHkiOiJjbGllbnQtY3JlZGVudGlhbHMifQ.YSY6hAO_9XYEKjmR1V14liCcyWlJe3_uhFB5MAFO7AfkgMsk1GNUMP2lLlIYw2-fuEHrfuPDzr-ymaLCAJ28zI0qiavLrHdXSKNQtwWVZi9gDNuhaHKjFmEUdzUStZjDon71mQ67M_vxm_QT7keXsjvjoPMoXd5ro2F4FQNWYOO36aGlNVWU2g3Q6pay1L2x0KwNjKMXNSzBWv386WO-j7Shn6BAXCUUj7laVu5XXXtyLrcozVMyOVq5nFnXlihYpEtie1OD3U0tg0L5yPndgmFoD4YQW0SmlqIc50PXB_iLunKYSl1mlmQYOpUW4Fjts0TrKkr5-2Gr7ak9EY8zAA\",\"expires_in\":86400,\"token_type\":\"Bearer\"}%\n```\n\nCopy the entire access token (without the quotes). If you have any trouble, go to [jwt.io](https://jwt.io) and paste this token into the JWT parser to verify that you copied a valid token. If it doesn't parse, you copied it wrong.\n\n## Perform an authenticated query!\n\nNow that everything is ready, try querying the running GraphQL API.\n\nMake sure to substitute your access_token above into the request below.\n\n```\n# The Authorization header contains my test token. Substitute your own token here.\ncurl --request POST \\\n  --url http://localhost:4000/graphql \\\n  --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkF3ZFVIcWNoUUw5NENoeGxZSDBzRSJ9.eyJpc3MiOiJodHRwczovL2Rldi1jYy1leGFtcGxlLnVzLmF1dGgwLmNvbS8iLCJzdWIiOiJqTUdxUkxiSU1ZZjlVUWhaczZpNWY5bWdraVpwRDBZdEBjbGllbnRzIiwiYXVkIjoiaHR0cHM6Ly9ncmFwaHFsYXV0aC5leGFtcGxlL2dyYXBocWwiLCJpYXQiOjE2MjYxMjU4MzksImV4cCI6MTYyNjIxMjIzOSwiYXpwIjoiak1HcVJMYklNWWY5VVFoWnM2aTVmOW1na2lacEQwWXQiLCJndHkiOiJjbGllbnQtY3JlZGVudGlhbHMifQ.YSY6hAO_9XYEKjmR1V14liCcyWlJe3_uhFB5MAFO7AfkgMsk1GNUMP2lLlIYw2-fuEHrfuPDzr-ymaLCAJ28zI0qiavLrHdXSKNQtwWVZi9gDNuhaHKjFmEUdzUStZjDon71mQ67M_vxm_QT7keXsjvjoPMoXd5ro2F4FQNWYOO36aGlNVWU2g3Q6pay1L2x0KwNjKMXNSzBWv386WO-j7Shn6BAXCUUj7laVu5XXXtyLrcozVMyOVq5nFnXlihYpEtie1OD3U0tg0L5yPndgmFoD4YQW0SmlqIc50PXB_iLunKYSl1mlmQYOpUW4Fjts0TrKkr5-2Gr7ak9EY8zAA' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\"query\":\"query {\\n  hello\\n}\"}'\n```\n\nYay! We got a response:\n\n```\n{\n    \"data\":{\n        \"hello\": \"Hello Martin!\"\n    }\n}\n```\n\n### Unauthenticated queries\n\nNow try access without the token:\n\n```\ncurl -v --request POST \\\n  --url http://localhost:4000/graphql \\\n  --header 'Content-Type: application/json' \\\n  --data '{\"query\":\"query {\\n  hello\\n}\"}'\n```\n\nAnd we receive a nice unauthorized response:\n\n```\n\u003e POST /graphql HTTP/1.1\n\u003e Host: localhost:4000\n\u003e User-Agent: curl/7.64.1\n\u003e Accept: */*\n\u003e Content-Type: application/json\n\u003e Content-Length: 31\n\u003e\n\u003c HTTP/1.1 401 Unauthorized\n\u003c X-Powered-By: Express\n\u003c WWW-Authenticate: Bearer realm=\"graphql\"\n\u003c Content-Type: application/json; charset=utf-8\n\u003c Content-Length: 39\n\u003c ETag: W/\"27-M+NKBmJicHoEHY9N+3z9/MyjfrA\"\n\u003c Date: Mon, 12 Jul 2021 23:39:25 GMT\n\u003c\n{\"errors\":[{\"message\":\"Unauthorized\",\"extensions\":{\"code\":\"credentials_required\"}}]}\n```\n\nSimilarly, an invalid token returns:\n\n```\n{\"errors\":[{\"message\":\"Unauthorized\",\"extensions\":{\"code\":\"invalid_token\"}}]}\n```\n\n## Acknowledgements\n\nThe basic graphql express example was copied from this\n[GraphQL.org tutorial](https://graphql.org/graphql-js/running-an-express-graphql-server/).\n\nThe Auth0 login middleware was copied from\n[Auth0 node tutorial](https://auth0.com/docs/quickstart/backend/nodejs/01-authorization).\n\nNote: I had to mess around with the Auth0 config a bit, but it took less than an hour to get this working. To speed up getting your token to test API calls, use the example cURL found\nby clicking on the API you created [here](https://manage.auth0.com/dashboard/us/dev-cc-example/apis) then choosing the 'Test' submenu.\n\nThank you to my friends a [Cloud City Development](https://cloudcity.io) for giving me the time and support to create this example.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartinemde%2Fgraphql-node-auth-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmartinemde%2Fgraphql-node-auth-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartinemde%2Fgraphql-node-auth-example/lists"}