- Next.js 8 for building the sample serverless react app
- Apollo Client for GraphQL querying
- Node.js server for JWT authentication
- Hasura GraphQL Engine for GraphQL APIs with permissions
Let's get the backend up and running before configuring the Next.js 8 app.
Hasura is an open-source engine that gives you realtime GraphQL APIs on new or existing Postgres databases, with built-in support for stitching custom GraphQL APIs and triggering webhooks on database changes.
Follow the instructions in the docs to deploy Hasura. Note the Heroku URL for GraphQL Endpoint. You will be configuring this in the app later.
Apply the migrations by following the instructions in this section to create the necessary database schema and permissions.
Now the backend is ready! You will be able to instantly query using Hasura GraphQL APIs. The endpoint will look like (https://myapp.herokuapp.com/v1alpha1/graphql). We will come back to this during the integration with the Next.js app.
Run JWT Server
We will now run the JWT server locally to handle signup and login requests from the Next.js app.
Now, get the database URL from Heroku by heading to the settings page of the app.
Replace DATABASE_URL with the value obtained from Heroku config.
Configure JWT with Hasura
Now that the JWT server is ready, we need to configure Hasura to use the JWT Secret. The env
HASURA_GRAPHQL_JWT_SECRET should be set like this:
<AUTH_PUBLIC_KEY> is your RSA public key in PEM format, with the line breaks escaped with "\n". This was generated just above.
In order to configure the JWT Secret we also need to set the admin secret. Head over to docs to set this up on Heroku.
Run the Next.js App
Both the JWT server and Hasura GraphQL Engine has been setup and configured.
Now let's run the Next.js app by running the following commands:
Configure the Heroku app url in
lib/init-apollo.js. Now install the dependenices, build the serverless bundle and run the app using the following commands.
Once you run the app, you should be getting a screen like the one below:
Apollo Client has been configured with an Auth Middleware which sets the Authorization header (if available).
We call a utility function called
getToken() which gets the auth token stored in the cookie and returns the token.
The actual implementation of signup and login sets the cookie with the token.
In the file
utils/auth.js, we handle the logic of what needs to be done once the server returns the token after successful signup/login.
Authorization using JWT
Now that the user is logged in, we would like to fetch only the articles written by the same user. The permissions have been configured in such a way that only the user who wrote the article will be able to fetch the data.
Head to the Heroku app URL to open Hasura console and navigate to Data->article->Permissions to see the permissions defined for the
The permission check looks like:
This means that when a request is being sent with
Authorization: Bearer <token>from the client, it will look for the
X-Hasura-User-Id value from the token payload and filter it for the
user_id column, ensuring that only logged in users get the data and also get only their data. The user has permissions to access all columns.
Protected Routes using HOC
Though we have handled authorized queries, we would like to restrict access to pages like
/articles at the route level because it is available only for logged in users. We again make use of an HOC to handle this.
When a navigation is triggered on a protected route, we call a utility helper method
auth which will fetch the token from the cookie using the
nextCookie module. In case the token is not available, then it will redirect to
We wrap the protected components like
articles using the
withAuthSync HOC which will take care of the redirects on the server.
After logging in, when you visit the articles page, you should be seeing the articles written by you.
Don't be surprised to see data being empty. You would need to insert articles tagging your user id in the Hasura console.
Deploy on Now
We can deploy this Next.js app on
now.sh with the
Do note that, the JWT server has to be deployed as well. The JWT server url has to be configured inside the Next.js app.
I have put together a boilerplate so that you can get started quickly!
Check it out on github.