Add user authentication

This commit is contained in:
Grégoire Delattre 2016-11-15 23:39:45 +01:00
parent 1bb5433b0d
commit 3701917869
6 changed files with 51 additions and 15 deletions

View File

@ -14,12 +14,14 @@
"bootstrap": "^3.3.6", "bootstrap": "^3.3.6",
"font-awesome": "^4.7.0", "font-awesome": "^4.7.0",
"jquery": "^2.2.4", "jquery": "^2.2.4",
"jwt-decode": "^2.1.0",
"react": "^15.3.2", "react": "^15.3.2",
"react-dom": "^15.3.2", "react-dom": "^15.3.2",
"react-redux": "^4.4.6", "react-redux": "^4.4.6",
"react-router": "^3.0.0", "react-router": "^3.0.0",
"react-router-redux": "^4.0.7", "react-router-redux": "^4.0.7",
"redux": "^3.6.0", "redux": "^3.6.0",
"redux-auth-wrapper": "^0.9.0",
"redux-logger": "^2.7.4", "redux-logger": "^2.7.4",
"redux-promise-middleware": "^4.1.0", "redux-promise-middleware": "^4.1.0",
"redux-thunk": "^2.1.0" "redux-thunk": "^2.1.0"

View File

@ -1,20 +1,29 @@
import React from 'react' import React from 'react'
import ReactDOM from 'react-dom' import ReactDOM from 'react-dom'
import { Router, Route, IndexRoute, Link, hashHistory } from 'react-router' import { bindActionCreators } from 'redux'
import { Provider } from 'react-redux' import { Provider, connect } from 'react-redux'
import { Router, Route, IndexRoute, IndexRedirect, Link, hashHistory } from 'react-router'
import { routerActions } from 'react-router-redux'
import { UserAuthWrapper } from 'redux-auth-wrapper'
// Root reducer
import rootReducer from './reducers/index' import rootReducer from './reducers/index'
// Action creators
import * as actionCreators from './actions/actionCreators'
// Store
import store, { history } from './store' import store, { history } from './store'
// Components
import NavBar from './components/navbar.jsx' import NavBar from './components/navbar.jsx'
import MovieList from './components/movie-list.jsx' import MovieList from './components/movie-list.jsx'
import UserLoginForm from './components/user-login.jsx' import UserLoginForm from './components/user-login.jsx'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import * as actionCreators from './actions/actionCreators'
class Main extends React.Component { class Main extends React.Component {
componentWillMount() {
this.props.isUserLoggedIn()
}
render() { render() {
return ( return (
<div> <div>
@ -44,14 +53,26 @@ function mapDispatchToProps(dispatch) {
const App = connect(mapStateToProps, mapDispatchToProps)(Main); const App = connect(mapStateToProps, mapDispatchToProps)(Main);
// Redirects to /login by default
const UserIsAuthenticated = UserAuthWrapper({
authSelector: state => state.userStore,
redirectAction: routerActions.replace,
wrapperDisplayName: 'UserIsAuthenticated',
predicate: user => user.isLogged,
failureRedirectPath: '/users/login',
})
const Authenticated = UserIsAuthenticated((props) => props.children);
ReactDOM.render(( ReactDOM.render((
<Provider store={store}> <Provider store={store}>
<Router history={history}> <Router history={history}>
<Route path="/" component={App}> <Route path="/" component={App}>
<IndexRedirect to="/users/login" />
<Route path="/users/login" component={UserLoginForm} /> <Route path="/users/login" component={UserLoginForm} />
<IndexRoute component={MovieList} /> <Route component={Authenticated}>
<Route path="/movies/popular" component={MovieList} /> <Route path="/movies/popular" component={MovieList} />
</Route> </Route>
</Route>
</Router> </Router>
</Provider> </Provider>
),document.getElementById('app')); ),document.getElementById('app'));

View File

@ -4,9 +4,6 @@ import { store } from '../store'
import { isUserLoggedIn } from '../actions/actionCreators' import { isUserLoggedIn } from '../actions/actionCreators'
export default class NavBar extends React.Component { export default class NavBar extends React.Component {
componentDidMount() {
this.props.isUserLoggedIn()
}
render() { render() {
const username = this.props.userStore.username; const username = this.props.userStore.username;
const isLoggedIn = username !== "" ? true : false; const isLoggedIn = username !== "" ? true : false;

View File

@ -5,6 +5,7 @@ const defaultState = {
userLoading: false, userLoading: false,
username: "", username: "",
isAdmin: false, isAdmin: false,
isLogged: false,
}; };
// This actions are generated from the promise middleware // This actions are generated from the promise middleware
@ -22,7 +23,7 @@ export default function userStore(state = defaultState, action) {
return updateFromToken(state, action.payload.data.token) return updateFromToken(state, action.payload.data.token)
case IS_USER_LOGGED_IN: case IS_USER_LOGGED_IN:
let localToken = localStorage.getItem('token'); let localToken = localStorage.getItem('token');
if (localToken === "") { if (!localToken || localToken === "") {
return state; return state;
} }
return updateFromToken(state, localToken) return updateFromToken(state, localToken)
@ -41,6 +42,7 @@ function updateFromToken(state, token) {
localStorage.setItem('token', token); localStorage.setItem('token', token);
return Object.assign({}, state, { return Object.assign({}, state, {
userLoading: false, userLoading: false,
isLogged: true,
isAdmin: decodedToken.isAdmin, isAdmin: decodedToken.isAdmin,
username: decodedToken.username, username: decodedToken.username,
}) })

View File

@ -3,11 +3,14 @@ import { syncHistoryWithStore } from 'react-router-redux'
import { hashHistory } from 'react-router' import { hashHistory } from 'react-router'
import thunk from 'redux-thunk' import thunk from 'redux-thunk'
import promise from 'redux-promise-middleware' import promise from 'redux-promise-middleware'
import { routerMiddleware } from 'react-router-redux'
// Import the root reducer // Import the root reducer
import rootReducer from './reducers/index' import rootReducer from './reducers/index'
const middlewares = [promise(), thunk]; const routingMiddleware = routerMiddleware(hashHistory)
const middlewares = [promise(), thunk, routingMiddleware];
// Only use in development mode (set in webpack) // Only use in development mode (set in webpack)
if (process.env.NODE_ENV === `development`) { if (process.env.NODE_ENV === `development`) {

View File

@ -1581,7 +1581,7 @@ hoek@2.x.x:
version "2.16.3" version "2.16.3"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
hoist-non-react-statics@^1.0.3, hoist-non-react-statics@^1.2.0: hoist-non-react-statics@^1.0.3, hoist-non-react-statics@^1.2.0, hoist-non-react-statics@1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb"
@ -1899,6 +1899,10 @@ jsprim@^1.2.2:
json-schema "0.2.3" json-schema "0.2.3"
verror "1.3.6" verror "1.3.6"
jwt-decode:
version "2.1.0"
resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-2.1.0.tgz#d3079cef1689d82d56bbb7aedcfea28b12f0e36a"
kind-of@^3.0.2: kind-of@^3.0.2:
version "3.0.4" version "3.0.4"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.0.4.tgz#7b8ecf18a4e17f8269d73b501c9f232c96887a74" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.0.4.tgz#7b8ecf18a4e17f8269d73b501c9f232c96887a74"
@ -2024,7 +2028,7 @@ lodash.isarray@^3.0.0:
version "3.0.4" version "3.0.4"
resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
lodash.isempty@^4.2.1: lodash.isempty@^4.2.1, lodash.isempty@4.4.0:
version "4.4.0" version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e"
@ -2699,6 +2703,13 @@ redux:
loose-envify "^1.1.0" loose-envify "^1.1.0"
symbol-observable "^1.0.2" symbol-observable "^1.0.2"
redux-auth-wrapper:
version "0.9.0"
resolved "https://registry.yarnpkg.com/redux-auth-wrapper/-/redux-auth-wrapper-0.9.0.tgz#4456a73f44ea8b1e996906127feffac890ba6913"
dependencies:
hoist-non-react-statics "1.2.0"
lodash.isempty "4.4.0"
redux-logger: redux-logger:
version "2.7.4" version "2.7.4"
resolved "https://registry.yarnpkg.com/redux-logger/-/redux-logger-2.7.4.tgz#891e5d29e7f111d08b5781a237b9965b5858c7f8" resolved "https://registry.yarnpkg.com/redux-logger/-/redux-logger-2.7.4.tgz#891e5d29e7f111d08b5781a237b9965b5858c7f8"