DEV Community

Cover image for User Authentication with Next.js

User Authentication with Next.js

Juan Olvera on February 28, 2019

Note: I wrote this post before API routes was released. I need to update the post to use the latest Next.js features. Meanwhile, you should read Th...
Collapse
 
ethanbonsignori profile image
Ethan Bonsignori

Hey Juan, I'm new to Next and this guide seems like it will be a huge help. I'm working on a school project and currently I'm using a decoupled express backend with a mongo database. I was going to use passport for user auth, but your guide seems really great. I thought I'd check with you to see what is the better option. Is it possible to use your guide here and change the backend files to work with express? I'm pretty new to this stuff so I appreciate any guidance.

Collapse
 
jolvera profile image
Juan Olvera

Hey Ethan.

Yes, you can use Express and Passport. Although, you could write helper functions to issue and verify JWTs using jsonwebtoken, since the Next.js app will manage most of the user authentication/authorization logic.

If you are using Now 2 to deploy, you could even avoid Express and Passport altogether.

But answering your question, yes you can implement what I did in the tutorial to work with Express.

Collapse
 
flolege profile image
flolege • Edited

Hi Juan - first many thanks for this very useful article. Especially for beginners like me this helps a lot.

I am going through your description and have a question: in www-pages-login.js you generate a environment-dependent URL. Why is that actually needed? The login will always be triggered by the user via the frontend, right? So actually only the frontend URL is needed. Please let me know if I am wrong and if yes why :)

Many thanks!

Collapse
 
jolvera profile image
Juan Olvera • Edited

Hey flolege, you are very welcome!

When you are using Next.js, the first load of your site will always be from the server, then it will hydrate the site using React. So, we need to check where the request is coming from and get the host from either the server or the client.

Right now we are working on a simplified Authentication example with way less code and easier to understand.

However, that way to get the host should be for development only. And it's meant to be used with Now 2, because every time you deploy you get a new URL. In a regular application, you probably know what's your development and production URLs and you should use those, using environment variables.

I hope I answered your question if not let me know.

Collapse
 
flolege profile image
flolege

Hey Juan, thanks for your reply. I think I understand. Since the first load is on the server, we do not have access to the window object. So we have to retrieve it another way. many thanks!

Collapse
 
mustafaalfar profile image
mustafa-alfar • Edited

could you please clarify why you use micro package ?,
and are api/login and api/profile backend files ?
I've read its description and I didn't understand the main idea?

Collapse
 
jolvera profile image
Juan Olvera • Edited

Hey Mustafa!

Let's clarify some points before the explanation.

The application in the example is built as a monorepo and it's meant to be deployed at Now.

The files that are in the api/ folder compose the backend. The files inside the www/ folder are the frontend, in this case, the Next.js application.

In the backend, every file it's a single function and works as an API endpoint. They are serverless lambdas, you can think of them as a route in an Express.js application, but this is an oversimplification.

So, the Micro package contains utilities that make it easier to deploy this kind of applications.

For example, if I need to parse JSON, with Express.js I'd have to include the entire library, setup middlewares, and so on. With Micro we can use a function from the package and pass the request as a parameter, e.g.,

// example.js

const { json } = require('micro');

const fn = (req, res) => json(req);

modules.export = fn;

so, if we save this code into a file called example.js we can deploy it to Now along with a now.json file and get a functional endpoint that we can call with fetch or axios.

You can clone the example repo and deploy it following its instructions. Once you see it working, take a look at the code, at the logs in Now and you will get a better idea of how it works.

Ping me on Twitter at @_jolvera if you have more questions and we can chat about it.

I hope this helps!

Collapse
 
mustafaalfar profile image
mustafa-alfar

thank you for this elaborating,
I'll try it out, and I'll tell you if I struggled with something.

Collapse
 
stokescomp profile image
Michael Stokes

Your link to monorepo doesn't exist.

Thread Thread
 
jolvera profile image
Juan Olvera

Hey, Michael.

ZEIT changed their repos. The replacement for the monorepo is gatsby-functions.

Collapse
 
helloitsm3 profile image
Sean

Good job on the tutorial. It really helped me to better understand how to do authentication in Nextjs when deploying to Now v2. I recently started a NextJS project and implemented Express as my backend to do user authentication, however, I only found out that it's not supported in Now v2 and have to re-write the code.

Collapse
 
jamesvibar profile image
vibar

Hi Juan! Thank you so much for this very detailed tutorial. Aside from helping me with auth, I also got a better understanding on how getInitialProps work! :D

I just have a question. I'm in Next 9 and when I try to use withAuthSync HOC. I get a UnhandledPromiseRejectionWarning: Error: No router instance found. error whenever I visit the page with the withAuthSync HOC.

You should only use "next/router" inside the client side of your app..

Collapse
 
harveyjones282 profile image
Harvey Jones • Edited

An incredibly detailed blog. I though I would have to gather scraps and bits from a dozen different places but you made my work easier. Thanks.

Another authentication which I wasn't able to find anywhere else was next.js with redux jwt authentication. Just like your blog I finally found it in one place. Just going to drop it here.
blog.carbonteq.com/next-js-redux-s...
Hope it helps someone else.

Collapse
 
jolvera profile image
Juan Olvera

This is awesome. Thank you for the link!

Collapse
 
giovannipds profile image
Giovanni Pires da Silva • Edited

Hi Juan! Excellent tutorial. The thing I most like it is the sync logout, that's freak!

I'll leave you one question: I'll be implementing this on my app, I'm already doing the HOCs, cookies, etc. but I'd like to redirect on logout only if I'm on a protected route. Do you have suggestion about handling this? A way to check if the page's using the HOC? If there's no other way, I'd probably end creating like a routes.js to know what page's protected but seems like a double logic for the same thing. Any approach would be good to hear.

Thank you very much!

Collapse
 
pedromagalhaes profile image
Pedro Magalhães

Nice tutorial! Would be even better to implement this example with React Hooks. Anyways good job!

Collapse
 
jolvera profile image
Juan Olvera

Hey Pedro,

When I started writing the tutorial, Hooks weren't released yet. I will wait a bit before I update them to Hooks, tho.

Thanks for the reply!

Collapse
 
pedromagalhaes profile image
Pedro Magalhães

No worries. Its pretty cool the tutorial.

Im using similiar tech stack in my company for more than an year and i really enjoy it, i.e. react+next+node+hoc+recompose+redux+eslint+styled components etc.

Now im currently doing a backoffice with same tech stack, but this time using hooks for component lifecycle, and context with reducers instead of redux. So far so good. I love it.

Anyways keep up with this kind of tutorials. I really enjoy to see them.

Cheers

Collapse
 
shikhaarora4 profile image
Shikha

I have tried to follow all the steps, but get this error when i try to deploy using now.
ENOENT: no such file or directory, stat '/Users/xxxxxxxx/SourceCode/node/my-app/node_modules/node-pre-gyp/node_modules/.bin/detect-libc'
Am I doing something wrong?

Collapse
 
kenshinman profile image
Kehinde Orilogbon

Hey, thanks for this wonderful explanation. Just wondering, how do I know current user or authentication in sub components? Thanks

Collapse
 
kaloraat profile image
Ryan (Narayan) Dhungel

Thanks for this great post. Can you please make the source code available. Is it in github?

Collapse
 
kaloraat profile image
Ryan (Narayan) Dhungel
Collapse
 
jolvera profile image
Juan Olvera

Hey Ryan!

Yes. That's the code.

Collapse
 
standingdreams profile image
Douglas Rogers

Was this article created prior to the API Route? If not, why did you opt to not place the backend code there?

Collapse
 
jolvera profile image
Juan Olvera

Hey Douglas,

Yes. It was created before API routes. This post is outdated now. I will add a note to go to auth0.com/blog/ultimate-guide-next... instead.

Collapse
 
nguyenquangtin profile image
Tony Tin Nguyen

Thank you for the detail guide.

Collapse
 
jolvera profile image
Juan Olvera

You are welcome!

Collapse
 
omelab profile image
Abu Bakar Siddique

Hellow i have faceing this problem can any one fhelp me

./pages/login.js
Attempted import error: 'login' is not exported from '../utils/auth'.