Permalink
Browse files

Protect frontend routes

  • Loading branch information...
bnhansn committed Oct 21, 2016
1 parent bb46dd4 commit 10ee0720954da9312bb49d09b5d83edffcacd833
@@ -34,12 +34,17 @@ export function logout(router) {
}
export function authenticate() {
return dispatch => api.post('/sessions/refresh')
.then((response) => {
setCurrentUser(dispatch, response);
})
.catch(() => {
localStorage.removeItem('token');
window.location = '/login';
});
return (dispatch) => {
dispatch({ type: 'AUTHENTICATION_REQUEST' });
return api.post('/sessions/refresh')
.then((response) => {
setCurrentUser(dispatch, response);
})
.catch(() => {
localStorage.removeItem('token');
window.location = '/login';
});
};
}
export const unauthenticate = () => ({ type: 'AUTHENTICATION_FAILURE' });
@@ -0,0 +1,31 @@
// @flow
import React from 'react';
import { Match, Redirect } from 'react-router';
type Props = {
component: any,
pattern: string,
exactly?: boolean,
isAuthenticated: boolean,
willAuthenticate: boolean,
}
const MatchAuthenticated = ({
pattern,
exactly,
isAuthenticated,
willAuthenticate,
component: Component,
}: Props) =>
<Match
exactly={exactly}
pattern={pattern}
render={(props) => {
if (isAuthenticated) { return <Component {...props} />; }
if (willAuthenticate) { return null; }
if (!willAuthenticate && !isAuthenticated) { return <Redirect to={{ pathname: '/login' }} />; }
return null;
}}
/>;
export default MatchAuthenticated;
@@ -0,0 +1,31 @@
// @flow
import React from 'react';
import { Match, Redirect } from 'react-router';
type Props = {
component: any,
pattern: string,
exactly?: boolean,
isAuthenticated: boolean,
willAuthenticate: boolean,
}
const RedirectAuthenticated = ({
pattern,
exactly,
isAuthenticated,
willAuthenticate,
component: Component,
}: Props) =>
<Match
exactly={exactly}
pattern={pattern}
render={(props) => {
if (isAuthenticated) { return <Redirect to={{ pathname: '/' }} />; }
if (willAuthenticate) { return null; }
if (!willAuthenticate && !isAuthenticated) { return <Component {...props} />; }
return null;
}}
/>;
export default RedirectAuthenticated;
@@ -1,17 +1,20 @@
// @flow
import React, { Component } from 'react';
import { BrowserRouter, Match, Miss } from 'react-router';
import { BrowserRouter, Miss } from 'react-router';
import { connect } from 'react-redux';
import { authenticate } from '../../actions/session';
import { authenticate, unauthenticate } from '../../actions/session';
import Home from '../Home';
import NotFound from '../../components/NotFound';
import Login from '../Login';
import Signup from '../Signup';
import MatchAuthenticated from '../../components/MatchAuthenticated';
import RedirectAuthenticated from '../../components/RedirectAuthenticated';
type Props = {
authenticate: () => void,
unauthenticate: () => void,
isAuthenticated: boolean,
willAuthenticate: boolean,
}
class App extends Component {
@@ -20,18 +23,23 @@ class App extends Component {
if (token) {
this.props.authenticate();
} else {
this.props.unauthenticate();
}
}
props: Props
render() {
const { isAuthenticated, willAuthenticate } = this.props;
const authProps = { isAuthenticated, willAuthenticate };
return (
<BrowserRouter>
<div style={{ display: 'flex', flex: '1' }}>
<Match exactly pattern="/" component={Home} />
<Match pattern="/login" component={Login} />
<Match pattern="/signup" component={Signup} />
<MatchAuthenticated exactly pattern="/" component={Home} {...authProps} />
<RedirectAuthenticated pattern="/login" component={Login} {...authProps} />
<RedirectAuthenticated pattern="/signup" component={Signup} {...authProps} />
<Miss component={NotFound} />
</div>
</BrowserRouter>
@@ -40,6 +48,9 @@ class App extends Component {
}
export default connect(
null,
{ authenticate }
state => ({
isAuthenticated: state.session.isAuthenticated,
willAuthenticate: state.session.willAuthenticate,
}),
{ authenticate, unauthenticate }
)(App);
@@ -1,19 +1,32 @@
const initialState = {
isAuthenticated: false,
willAuthenticate: true,
currentUser: {},
};
export default function (state = initialState, action) {
switch (action.type) {
case 'AUTHENTICATION_REQUEST':
return {
...state,
willAuthenticate: true,
};
case 'AUTHENTICATION_SUCCESS':
return {
...state,
willAuthenticate: false,
isAuthenticated: true,
currentUser: action.response.data,
};
case 'AUTHENTICATION_FAILURE':
return {
...state,
willAuthenticate: false,
};
case 'LOGOUT':
return {
...state,
willAuthenticate: false,
isAuthenticated: false,
currentUser: {},
};

0 comments on commit 10ee072

Please sign in to comment.