1
\$\begingroup\$

I'm trying to implement safe routes and checking if the user is authorized using only Context API.

I'm also trying to avoid that the user can see a PrivateRoute, but I'm not sure if I coverred all edge cases.

Also, is there a better way of doing this? Better implemantation or aproach to this?

I just don't want to use Redux or external libraries.

I made a gist but I'm also adding the full code here.

Auth.jsx

import React, { useState, useEffect } from 'react'
import PropTypes from 'prop-types'
import { checkIsAuthenticated, authSignUp, authLogin, authLogout } from '../../services/auth'

export const AuthContext = React.createContext({})

export default function Auth({ children }) {

    const [isAuthenticated, setIsAuthenticated] = useState(false)
    const [isLoading, setIsLoading] = useState(true)

    useEffect(() => {
        checkAuth()
    }, [])

    const checkAuth = () => checkIsAuthenticated()
        .then(() => setIsAuthenticated(true))
        .catch(() => setIsAuthenticated(false))
        .then(() => setIsLoading(false))

    const login = credentials => authLogin(credentials)
        .then(setIsAuthenticated(true))
        .catch(error => {
            alert(error)
            setIsAuthenticated(false)
        })

    const logout = () => {
        authLogout()
        setIsAuthenticated(false)
    }

    const signUp = credentials => authSignUp(credentials)
        .then(setIsAuthenticated(true))
        .catch(error => {
            alert(error)
            setIsAuthenticated(false)
        })

    return (
        <AuthContext.Provider value={{ isAuthenticated, isLoading, login, logout, signUp }}>
            {children}
        </AuthContext.Provider>
    )
}

Auth.propTypes = {
    children: PropTypes.oneOfType([
        PropTypes.func,
        PropTypes.array
    ])
}

PrivateRoute.jsx

import React, { useContext } from 'react'
import { Route, Redirect } from 'react-router-dom'
import PropTypes from 'prop-types'
import { AuthContext } from '../Auth/Auth'
import Loading from '../../views/Loading/Loading'

const PrivateRoute = ({ component: Component, ...otherProps }) => {

    const { isAuthenticated, isLoading } = useContext(AuthContext)

    return (
        <Route
            {...otherProps}
            render={props => (
                !isLoading
                    ?
                    (
                        isAuthenticated
                            ?
                            <Component {...props} />
                            :
                            <Redirect to={otherProps.redirectTo ? otherProps.redirectTo : '/signin'} />
                    )
                    :
                    <Loading />
            )}
        />
    )

}

PrivateRoute.propTypes = {
    component: PropTypes.func.isRequired
}

export default PrivateRoute

example.jsx

import React from 'react'
import { Switch, Route } from 'react-router-dom'
import PrivateRoute from './components/PrivateRoute/PrivateRoute'
import Auth from './components/Auth/Auth'


import Header from './components/Header/Header'
import HomePage from './views/HomePage/HomePage'
import SignUp from './views/SignUp/SignUp'
import SignIn from './views/SignIn/SignIn'
import FormList from './views/FormList/FormList'
import PageNotFound from './views/PageNotFound/PageNotFound'

export default function App() {
    return (
        <div>
            <Auth>
                <Header />
                <Switch>
                    <Route exact path="/" component={HomePage} />
                    <Route path="/signup" component={SignUp} />
                    <Route path="/signin" component={SignIn} />
                    <PrivateRoute path="/forms" component={FormList} />
                    <Route component={PageNotFound} />
                </Switch>
            </Auth>
        </div>
    )
}
\$\endgroup\$
4
  • \$\begingroup\$ While there are bound to be more promising places to seek useful feedback on security implications, you are welcome to post your code here at Code Review to seek improvement when you are ready for feedback and criticism on any aspect of the code. \$\endgroup\$
    – greybeard
    Apr 30, 2019 at 5:17
  • \$\begingroup\$ Here is the right place to ask about Potential security issues, so my post is correct? \$\endgroup\$
    – Vencovsky
    Apr 30, 2019 at 11:02
  • 1
    \$\begingroup\$ Basically, you are reducing your change of a good review by suggesting you're only interested in security. That's what graybeard is kindly warning you for. Less relevant: I was wondering about the optimistic 100% Secure implementation in the title. One thing I have learned is that nothing is ever a 100% secure. The moment you start thinking that, the percentage has already dropped markedly. \$\endgroup\$ Apr 30, 2019 at 12:43
  • \$\begingroup\$ @KIKOSoftware Thanks for your comment, now I understand much better, thanks for the advice! \$\endgroup\$
    – Vencovsky
    Apr 30, 2019 at 12:50

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.