User authentication with next.js (and Apollo GraphQL)
As you might know, there is no official next.js authentication example yet. It’s on the way, but the relevant issue has been open for about 5 months now, and a pull request has been put on hold.
Meanwhile, many people have come forth with their own boilerplates and examples, yet the whole issue is quite tricky.
The reason behind this is that next.js provides server-side-rendering and code splitting out of the box, which means a proper authentication mechanism needs to work seamlessly between client and server and across routes. Additional complexity comes when you consider the following aspects:
- Is the authentication service part of the next.js app or an external service?
- What if you want to provide multiple authentication strategies?
- Is the data API (think a REST or a GraphQL endpoint) running in a process that’s separate from the authentication service and/or the next.js server?
In the most complex case you have an authentication server, an API server, and the next.js server running separately. For the authentication mechanism to work correctly, it needs to instantiate many separate user sessions:
- client — API,
- client — next.js
- next.js — API
and possibly even
- client — auth server
- next.js — auth server
depending on the capabilities of the auth server. I have yet to encounter a solution that works for this scenario.
Ooth
Looking for a solution, about a month ago I formulated a draft proposal about an extensible user accounts system for node, which I called ooth. Meanwhile I’ve been working on it a lot (find it on Github).
Working examples include:
- A Create-React-App communicating with a GraphQL API and an Ooth server (all running as separate microservices, the authentication mechanism involves JWT to establish the session with the GraphQL API)
- Another Create-React-App communicating with a single GraphQL API running in the same process as the Ooth server (same process = same session, no JWT needed)
And finally, as released today:
It still doesn’t solve the more complex scenarios, with these running as separate microservices, but at least it allows you to authenticate isomorphically towards your API without having to relying on an external service, or have to reimplement your own username/password system.
Future work
For my personal use case, I’m quite happy with the single service approach for now — it does make everything a lot easier. In the long run a microservice-oriented architecture will be more elegant. I believe there are solutions to the complexities mentioned above, yet I don’t really need everything to run in a separate microservice for now. If you are interested in such a feature, I’ll be glad to hear your feedback.
As a consequence, I’m going to continue focusing on the next.js example to create a fully functional showcase with a nice UI.
Additionally I’m going to expand ooth’s capabilities to login with Facebook and Google. Are you interested in an other strategy? Let me know: if it already exists as a passport.js strategy it should be easy to wrap it with the additional logic needed for ooth.
You can follow news about ooth on twitter and of course on medium by clicking on “subscribe” here below.
Update: I created a node.js (next.js) starter library that provides the GUI side of Ooth, called Staart. Check it out live here!