Skip to content

Instantly share code, notes, and snippets.

@overthemike
Last active August 21, 2018 20:54
Show Gist options
  • Save overthemike/2a94365769b38df34fd7db850cd57ca8 to your computer and use it in GitHub Desktop.
Save overthemike/2a94365769b38df34fd7db850cd57ca8 to your computer and use it in GitHub Desktop.
import React from 'react'
import { BrowserRouter as Router, Route, Link, Redirect } from 'react-router-dom'
import { Authentication, AuthRoute } from './Authentication'
import Login from './Login'
import Public from './Public'
import Protected from './Protected'
const App = props => (
<Router>
<Authentication
redirectUrl='/login'
defaultRedirect='/'
>
<div>
<ul>
<li><Link to="/public">Public Page</Link></li>
<li><Link to="/protected">Protected Page</Link></li>
</ul>
<Route exact path="/" render={() => (
<Redirect to="/login" />
)} />
<Route path="/public" component={Public} />
<Route path="/login" component={Login} />
<AuthRoute path="/protected" component={Protected} />
</div>
</Authentication>
</Router>
)
export default App
import React, { Component } from 'react'
import { Route, Redirect } from 'react-router-dom'
const AuthContext = React.createContext({
isAuthenticated: false,
redirectUrl: '/login',
defaultRedirect: '/'
})
export class Authentication extends Component {
state = {
isAuthenticated: false
}
static defaultProps = {
redirectUrl: '/login',
defaultRedirect: '/'
}
signin = (cb) => {
setTimeout(() => {
this.setState({ isAuthenticated: true})
cb()
}, 300)
}
signout = () => {
this.setState({ isAuthenticated: false })
}
render() {
const value = {
isAuthenticated: this.state.isAuthenticated,
redirectUrl: this.props.redirectUrl,
signin: this.signin,
signout: this.signout
}
return (
<AuthContext.Provider value={value}>
{this.props.children}
</AuthContext.Provider>
)
}
}
export const AuthRoute = ({ component: Component, ...rest }) => (
<AuthContext.Consumer>
{ ({ isAuthenticated, redirectUrl }) => (
<Route {...rest} render={(props) => (
isAuthenticated
? <Component {...props} />
: <Redirect to={{
pathname: redirectUrl,
state: { from: props.location }
}}/>
)
}/>
)}
</AuthContext.Consumer>
)
export function withAuth(Component) {
return props => (
<AuthContext.Consumer>
{context => (
<Component {...context} {...props} />
)}
</AuthContext.Consumer>
)
}
import React, { Component } from 'react'
import { withAuth } from './Authentication'
import { Redirect } from 'react-router-dom'
class Login extends Component {
state = {
redirectToReferrer: false
}
login = () => {
this.props.signin(() => {
this.setState({ redirectToReferrer: true })
})
}
logout = () => {
this.props.signout()
}
render() {
const { from } = this.props.location.state || { from: {pathname: this.props.defaultRedirect }}
const { redirectToReferrer } = this.state
if (redirectToReferrer) {
return <Redirect to={from} />
} else {
return (
<div>
<p>You must log in to view the page at {from.pathname}</p>
<button onClick={this.login}>Log In</button>
</div>
)
}
}
}
export default withAuth(Login)
import React, { Fragment } from 'react'
import { withAuth } from './Authentication'
const Protected = (props) => (
<Fragment>
<h3>Protected</h3>
<button onClick={props.signout}>Logout</button>
</Fragment>
)
export default withAuth(Protected)
import React from 'react'
const Public = () => <h3>Public</h3>
export default Public
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment