NextJS auth with an external server - javascript

I'm working with auth in Nextjs, I'm wondering what is the best strategy to handle authentication in NextJS ?
Here my services structure :
If I understand well I have to handle the server side rendering in NextJS, so I understand I have to put cookies from my external server to my NextJS client, then handle the server side rendering checkings. To do that I assume I have to create connection between the NextJS server and the other services. Before dive more deeper in the subject I would discuss with you about the possibilities available to me. It seems the NextJS auth is a subject in plain development.
Any hint would be great,
Thanks

I've recently added an example with cookie auth which explains what you are trying to do on the frontend.
For the backend, optimally you'll have your API in an external server, apart from the server you use for rendering your Next.js app. This API will handle the database and the token creation business. Then the basics of the authentication are like this:
The client POST a request with username and password to the server.
The server gets the request and generate a token based on the data received.
If everything went okay validating the data, the server responds with the token, e.g., { token: "secrettoken" }.
The client receives the token and saves it in a cookie. Optionally you redirect the user to the /dashboard or /profile if everything is okay.
The client, on restricted pages, will check if the cookie exists and optionally validate that against the server, you do this last part in getInitialProps. If the cookie validation fails you redirect the user away.
I've created a small library to abstract this logic.
So in the end, your Next.js app shouldn't know what's happening in the server, it only should receive the token, save it, validate it, and redirect the user if something is wrong.
How you want to handle the token creation, on the external server, is up to you.

Check out this thread. There are several examples of how to do Authentication with JWT, OAuth etc throughout the thread. You'll see that the examples are utilizing getInitialProps and there are several examples utilizing cookies throughout to extract the Authentication tokens.
You'll have to write a custom server.js file using express.js to serve the tokens through your route requests. I'm assuming by "external server" you mean some third party Authenticator using OAuth or OpenId protocols to retrieve tokens. If so, you're right to say that you'll need to request the tokens (or Authentication mechanism) from those external services and then decide how you're going to utilize them in your own client. You'll probably be using getInitialProps to do what you need to do with your Authentication tokens in the client once you are rendering to the browser.
More examples of Authentication here -- one for firebase and another for Apollo.

Just to add to the answers if you want to use Auth0 specifically. In the interview on http://www.fullstackradio.com/112 around the 1:06 min mark Guillermo Rauch mentioned that if he were to implement authentication all over again he would use Auth0, so I created a minimal repo using Auth0 and Nextjs with Serverless functions.
Like #jolvera suggested there is an API in an external server, apart from the server used for rendering the Next.js app. This API is located in ./auth/auth.js. It handles the token creation business, and could be extended to handle the database.
The HOC component in ./utils/withAuth.js calls the auth.js lambda for the user information, and is only able to retrieve it if the client side is authorized. Otherwise the user information is undefined. Additionally there is an event listener similar to the one in with-cookie-auth which syncs logouts across tabs.
Also one other note, don't get confused with the Nextjs example on Auth0's blog. That example is extending the Nextjs server, and isn't the solution you want if you are deploying Next to serverless. It doesn't have the separation of concerns with page routing and authentication.

Related

How is nuxt/auth really secure?

Let's imagine a client opens your nuxt.js website on the index page. From there, they authenticate (you used #nuxtjs/auth-next for that purpose). Then they move to a secure page that only authenticated users can see. This secure page is a .vue file in your "pages" folder with middleware: ["auth"].
Now, how is this page really secure ?
I mean, couldn't a malicious user temper with the page and access it without being authenticated anyway ? Because the "security" in this scenario is only implemented on the client side right ? [Edit]
Your application being an SPA at the end, if you want to bypass a middleware with it's security checkup, you could disable the JS on the page. But then, since no content is generated directly, you won't see anything because it's not here (as a static file).
If your app is isomorphic (basically has a ssr: true), the auth module will still disable the access to those pages (you can double check).
At the end, the critical info is received when:
you do have a valid JWT token (after some login)
you submit an HTTP query to the backend
the backend acknowledges it and the token is valid
the backend gives you the sensitive info via an HTTP response
At the end, your client side code doesn't need to be secure. If somebody somehow hacks your client side state and reaches the sensitive page, he will still not have a valid JWT token since the verification still happens on the backend.
The one that can be generated only when sending the proper credentials to the backend and having the backend validating those.
Now, how is this page really secure ?
The protected content is served from a request if a valid access token has been provided by the client.
The protected content is provided at runtime.
Because the "security" in this scenario is only implemented on the client side right ?
The security is not only implemented on the client side.
The premise is: The access token has been obtained securely through an authentication flow with an auth-server.
I recommend to read more about auth flows if this sounds unclear.
Auth0 has some good documentation on different flows.
https://auth0.com/docs/authorization/flows
Then, what is the best way to show a complex page to authenticated users only ?
The content is provided at run-time. Server-side or client-side.
There are some setup guides here for Nuxt.
Here is the first (Auth0) I found from the list.
https://auth.nuxtjs.org/providers/auth0
I don't know how updated those guides are, but the auth service providers tend to have updated guides themselves.

Preventing CSRF with an Express API and a React frontend

I have been reading around CSRF for the past few days and feel like I have a good grasp on what it is and how to prevent it. I am building a small Express/React application that will have a secure admin area for updating the app content and I want it to be protected from CSRF.
I understand that it is common for the server to generate the CSRF token and then send it to the client along with the view (page) that has been requested (the token can then be hidden in a HTML form input tag). However, my Express API does not serve HTML, it is a REST API that only returns JSON data. The UI is built with React, running on a different port from the server.
My question is; Where do I securely store a token generated on the server?
For example, if I log in as admin by hitting '/api/login', generate a token, and send it back to the client in the API response, what should I do with it now?
The original plan was to use Redux to store the token but from reading this post Is Redux secure?, this does not sound ideal.
I considered using React env variables but have also read that these are exposed in the build.
Obviously localStorage is also a bad idea...
I am really struggling to find a solution to this problem using the tools I am implementing i.e. Express/React
Any help, links, advice, criticisms would be appreciate, I want to learn to build apps with security in mind
I understand that it is common for the server to generate the CSRF token
The server needs to generate two CSRF tokens
and then send it to the client along with the view (page) that has been requested (the token can then be hidden in a HTML form input tag).
One token is commonly sent as a cookie, another can be sent as HTTP header. It doesn't need to be sent inside HTML body as a HTML form input tag (or any other part of the body) though it can be sent this way.
My question is; Where do I securely store a token generated on the server?
You don't have to store a token on the server. You can but you don't need to.
The original plan was to use Redux to store the token
The Redux store is on the client, in browser's memory. In theory one React component (that extracts the second CSRF token from server response) can temporarily store the token in the store so that another React component can get it from there and put into the next request before it's sent to the server.
Obviously localStorage is also a bad idea...
Yes
Any help, links, advice, criticisms would be appreciate, I want to learn to build apps with security in mind
Links
With Express is very common to use this middleware. The steps can be found here.
Criticisms
This is strictly speaking off topic in the context of CSRF related Q/A, but ...
The UI is built with React, running on a different port from the server.
That hints to the possibility of using react-scripts which start webpack-dev-server. It's fine for development, not good for deployment in production. However this is a separate topic, serving React app's build artifacts (.html file, script bundles) to webclients has nothing to do with CSRF attack and its mitigation.
I want to learn to build apps with security in mind
Then you might consider using one webserver instead of two (frontend to serve React app and backend to serve API responses). Using one server results in production deployment which is not only less complex and costly, but also more secure because two servers have larger attack surface and with one server you don't need to weaken security by using CORS.

Where and how to store service credentials on pure front-end application

I wish to build a pure front-end app with JavaScript running on client-side, i.e. browser. My app is supposed to make requests to 3rd part services, which require some sort of authentication method.
Backend frameworks provide config files for this sort of thing, but since JS code is all interpreted on the client machine, the config files cannot be part of the bundle.
Is there any way of securely storing the service API keys, credentials and such within the client or do I need a backend solution for this also?
Search for most popular frameworks (Angular and React) for config files resulted only in storing environment-specific URLs. I'm starting to think that I've hit a dead-end and this simply can't be done.
Depends... You don't want the user to be able to sniff out any secrets you have to send to the third party, but in the case of an Implicit Grant with OAuth2, you can actually initiate and complete it in the browser.
You'll redirect to the 3rd party for login/authentication, then the user will be sent back to you with an access token good for a period of time.
That token is actually sent in a URL fragment, per the spec, so it's being sent to the browser and NOT your server. If you want to get the access token to a server, you'd need front-end code to parse the URL fragment and send its contents.
If the API will allow you to connect from the browser, you could keep everything in the browser and not need a backend server to handle credentials. But not every API will allow purely front-end authentication and API calls.
So, it depends...
Can you store service api creds in the client cache, or in cookies etc? Yes. Will it be secure to send them over the wire and store in the browser? No.
If keeping credentials secure is part of the requirements, I would do the work to authenticate on the backend or use a third party service that does this for you.

How to set up session token between JS and PHP API?

I have designed a simple HTML/CSS and JS/jQuery application, and now it's the moment of authentication integration. On the server side, I have done a REST API which allows clients to get some data. But, now I want to authenticate each request with access and/or session token.
I read many websites to find agreements or advice to establish security between the client (JS) and the REST API (PHP), but unfortunately I found nothing or not interesting.
So I ask you to enlighten me (if you want) to know what to do, what to implement, conventions, etc.
What I read:
Designing a Secure REST (Web) API without OAuth
Token Based Authentication for Single Page Apps (SPAs)
I cannot post more links according to my reputation...
Just give me advice, ways how to store private token (RSA) or access/session token for API.
Don't hesitate to give your reaction, and tell me if I'm not exact or something else.
You need to use a token-based authentication for your REST API. JWTs are the best in this particular case.
Why Use JSON Web Tokens?
Tokens are stateless. The token is self-contained and contains all the information it needs for authentication. This is great for scalability as it frees your server from having to store session state.
JWTs can be generated from anywhere. Token generation is decoupled from token verification allowing you the option to handle the signing of tokens on a separate server or even through a different company such us Auth0.
JWTs have fine-grained access control. Within the token payload you can easily specify user roles and permissions as well as resources that the user can access.
This will be your typical authentication flow process:
A user signs up/logs in, during the login process, you generate a JSON web token from the server and return it to the client. Since you are using PHP, you can use this library for the generation and signing of the token.
Store the JWT returned to the client on the browser Web Storage(local/session storage). It can also be stored in a cookie.
For subsequent HTTP requests from the client to the server, you send the token via headers/query, then the server validates the token. If it's valid, the user is authenticated otherwise the user is rejected.
BTW, if you don't want to implement authentication yourself, you can use Auth0, check out VanillaJS SPA and PHP quickstart
I hope this information helps. Cheers!
Authenticating REST API's with JavaScript front-ends is difficult because the JavaScript code is completely readable by anyone visiting the site so storing any kind of login credentials is no good.
With a standard Server to Server set-up simply using basic auth over HTTPS is more than enough but basic auth is no good for JavaScript SPA's as the credentials are in plain view.
For SPA's you need to be looking at JSON WebTokens, as your back end is in PHP you need to be looking at PHP-JWT from firebase. You can get the code here: https://github.com/firebase/php-jwt or recommended using composer:
composer require firebase/php-jwt
The package makes implementing JWT super simple see the docs for a complete code example. Also check out the JWT for a complete break down https://jwt.io/
I suppose Jwt (https://jwt.io/) is good solution for your question.
On the client side you can store the token on the localStorage or some global variable (for SPA).
You can transfer token on the HTTP header or as request parameter. It works.
Also you can see https://auth0.com/blog/angularjs-authentication-with-cookies-vs-token/

Securing API with Node

I'm trying to build my first API to be consumed by a mobile application built with Ionic.
Before starting I'm looking into the architecture and I can not understand exactly how to make secure my API routes.
Let's say I have an endpoint like http://myapi/v1/get-items and my application doesn't need an user to be authenticated to view those items in the mobile app.
How should I protect that route from external queries, using Postman for example?
I wish that route to be not accessible unless is not requested by the application.
Looking on Google I can find many solution using basic authentication but all of those require an user to log in... What if my app doesn't have users to log in?
I'm a bit confused but I think there is a solution and I don't know it yet...
I hope you can help me to understand it.
EDIT:
My Question is totally different from the following: How to implement a secure REST API with node.js
I'm looking for solution that DO NOT require a User Authentication.
If you don't want to use User Auth through something like Passport then you can institute a whitelist in your Node API instead. express-ipfilter is an express middleware module that allows you to filter requests based on the request IP.
Requiring a login would be the cleanest and safest way to make sure your api remains private. However, if you want to keep external users out of your services without requiring a login, you will need to "sign" your requests. By that I mean doing something like encrypting a current timestamp on the client using a key known to both the server and the client app, adding that encrypted string as a header, receiving that header in your server, decrypting it and checking that it's not too old of a timestamp before you return a response.
It's not really safe (if someone can see the code they can see the encryption key) but it's an obstacle and it down't require logging in. See this for an example on encryption/decryption

Categories