Giter VIP home page Giter VIP logo

Comments (1)

zorgick avatar zorgick commented on June 10, 2024 1

Hi! I was asking the same question a while ago. Despite the fact that @manuelbieh gave me a quick and detailed response #100 I did follow his advice, but modified it for my purposes.

So you don't want to render a cheap login page for an authenticated user to request later a heavy main page with all them fancy images, large bundles and texts, right?

There 2 main things in my solution that really helped me out, which are http-only cookies and separation of authentication and routing.

Firstly, usage of http-only cookie shifts the weight of storing a user ID in webstorage, accessing its value on the client, protecting it from CRSF and sending it with each request from your shoulders onto the browser's. Browser will send it every time he sees your origin in the URL.

Secondly, routing needs to do only one thing in your app, respond to the path change in the URL and bring a user to a necessary page, depending on the state of the app. So there is no need to create something similar to react-router's private routes, but the logic stays the same - there are public routes and there are private routes.

So, provided a browser is using a http-only cookie, you don't have to worry about the initial request to your server, which will be for index.html (I suppose any proxy server in your network allows the request to reach the node server, which will SSR your page into a html file). You will always receive information about the user, because browser will send a token - user ID preserved in browser's internals. You will either receive it - that tells you user is authenticated and it is ok to let him through or he needs to update his expired token, OR you will not (your server didn't previously set a unique ID for this user, or the user cleared his browser internal storage).

The solution is rather simple, the store must have information about the user before being created. Thus, you need to check for the presence of a cookie, its value (it can be expired) and initialise the store with some initial state of the app, let's say, "profileType" of the user, which can be 'authenticated', 'unauthenticated' or better an empty string '', 'expired' and so forth.

Going further, there are two basic scenarios - authenticated and not authenticated user. Both of them are allowed to access a requested URL, but what will be returned in response differs and depends on the "profileType" in the store.

What you need is a HOC (well, it is not a pure HOF, but let's call it HOC) for each container (except the one where routing happens - App.js) that will act like an interceptor in express.
My example looks like this (I can show you only its API):


/**
 * auth is a HOC that checks provided conditions on mount and on nextUpdate
 * It receives 3 function arguments
 * @param {function} meetCondition - verify user identity
 * @param {function}  damnGoBack - function that is called when the condition above is not met (it can be redirect to login page or any other page or just a notifier)
 * @param {function} whenToCheck - due to the fact that it is HOC, any props change is registered. So you can tune when you want meetCondition to be invoked. (used in CDM(), CDUP() etc)
 */
const withAuth = auth(
  ({profileType}) => profileType !== 'unauthenticated',
  ({some props you need}) => customFunction(with those props),
  (nextProps, props) => nextProps.profileType !== props.profileType
)

withAuth(YourContainer)

Before rendering a component provided for a certain route it will check for your provided condition to be met and either grant access to the container OR do whatever you want it to do, in your case redirect to the login page to let the user proceed with authentication process.

This HOC allows you to follow flux architecture (the View changes based on the changes in the global state) and react on API request interceptors that require token to let the request knock on your DB door. If server API interceptor returns 'expired' or 'unauthenticated' (logged out in another open tab), this HOC will know it first.

There is yet a lot to mention, but I hope you got my idea and wish you to solve your problem)

from react-ssr-setup.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.