Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

need oauth 2 client implementation for react router

we have created our own oauth 2 server with authorization code implementation from below code base. https://github.com/FrankHassanabad/Oauth2orizeRecipes

but we are trying to integrate oauth2 client authentication in web application which includes react router and flux implementation.

we looked into many git repositories but not getting any proper way to do this.

is there any implementation which points us to how it can be achieved?

Thanks again.

UPDATE

we are looking into below repositories, but still not clear on how we make things work. like where to merge auth and oauth logic and what things to make server/client side.

https://github.com/rackt/react-router/tree/master/examples/auth-flow

https://github.com/andreareginato/simple-oauth2

https://github.com/LearnBoost/superagent-oauth

https://github.com/zalando/superagent-oauth2-client

like image 707
jit Avatar asked Jan 24 '16 15:01

jit


People also ask

How do you call OAuth2 API in React JS?

Here's how the application will look like: import React, { useState } from 'react' import Pizzly from 'pizzly-js' import Profile from './Profile' const App = () => { const [profile, setProfile] = useState() return ( <div className="App"> <h1>Hello!

How do you implement user authentication in React?

There are two main things your React application needs to do to sign on a user: Get an access token from an authentication server. Send the access token to your backend server with each subsequent request.

How do you implement authentication routes in React router 6?

import { Navigate } from "react-router-dom"; import { useAuth } from "../hooks/useAuth"; export const ProtectedRoute = ({ children }) => { const { user } = useAuth(); if (!user) { // user is not authenticated return <Navigate to="/" />; } return children; }; To redirect the user, we use the <Navigate /> component.


1 Answers

I'll attempt to explain my high level take authentication with react-router. You will need implementation on both server and client and there are a few decisions you need to make yourself. For this example I will be using redux for the flux library.

First you will need a mechanism to protect your routes, I do this with a higher order component like so:

// 'Components/requireAuthentication'

import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import SignIn from './SignIn'

export default (ChildComponent) => {
  class AuthenticatedComponent extends Component {
    static propTypes = {
      hasAuthToken: PropTypes.bool.isRequired
    };

    render () {
      const { hasAuthToken } = this.props
      return (hasAuthToken
        ? <ChildComponent {...this.props} />
        : <SignIn />
      )
    }
  }

  const mapStateToProps = ({session}) => (session)

  return connect(mapStateToProps)(AuthenticatedComponent)
}

The code here is quite simple, it exports a function that expects a react component as the only argument. This ChildComponent is the component you want to protect.

The hasAuthToken prop is the control here, if it is true then the ChildComponent will be rendered, otherwise it will render SignIn. Note, this process of rendering SignIn is fine if you don't care about SEO but you may want to redirect the user to a sign-in route if you do care about search engines indexing your protected routes.

Finally AuthenticatedComponent is connected to the redux store session state but this could easily be switched out to use any other flux library of your choosing. Simply put, it is subscribing to changes on session. If the hasAuthToken changes in value, the component will be re-rendered if it is presently mounted.

Now for the routes:

import { Route } from 'react-router'
import Container from './Components/Container'
import Private from './Components/Private'
import requireAuthentication from './Components/requireAuthentication'

export default (
  <Route path='/' component={Container}>
    <Route path='private' component={requireAuthentication(Private)}>
      <Route path='other' component={...} />
    </Route>
  </Route>
)

Here I am applying the requireAuthentication method (the default exported method from the code above) with the component I want to protect. This will keep pages from being shown unless the redux store session.hasAuthToken property is true and instead show the SignIn component.

Other routes nested under the protected component will also be protected because of the way react-router composes the routes.

At a high level the SignIn component should simply be a page with a normal <a href> (i.e. not react-router Link) to begin the Oauth2 handshake. The simple-oauth2 module has some nice examples on how to implement oauth2 server-side so I won't get into that here. If you're following those examples, it's the app.get('/auth', function (req, res) {}) endpoint you want to link the user to.

In the callback endpoint you will want to persist the token somehow (e.g. to your session (express-session will help out here) or to the database), then redirect the user back to your react app.

Now you'll need to get your session into the server-side redux store in preparation for it to be hydrated on the client. The redux docs explains how to do this on the Server Rendering page, specifically the Inject Initial Component HTML and State and The Client Side sections. At a minimum you'll need an object like this:

{
  hasAuthToken: (typeof req.session.token !== 'undefined')
}

Of course your actual implementation will depend entirely on how you store the token and provide it to the server-side request.

Hopefully this will get you started. This same process can be used for other kinds of authentication as well by replacing the Oauth2 link with a username and password form that your server handles as an XHR.

Best of luck.

like image 84
Marc Greenstock Avatar answered Sep 25 '22 05:09

Marc Greenstock