sipp11
7 years ago
11 changed files with 188 additions and 22 deletions
@ -1,3 +1,9 @@ |
|||||||
|
|
||||||
export const FIRST_INCREMENT_COUNTER = 'FIRST_INCREMENT_COUNTER' |
export const FIRST_INCREMENT_COUNTER = 'FIRST_INCREMENT_COUNTER' |
||||||
export const FIRST_ASSIGN_ID = 'FIRST_ASSIGN_ID' |
export const FIRST_ASSIGN_ID = 'FIRST_ASSIGN_ID' |
||||||
|
export const SET_TOKEN = 'SET_TOKEN' |
||||||
|
|
||||||
|
|
||||||
|
export const REQUEST_LOGIN = 'REQUEST_LOGIN' |
||||||
|
export const SUCCESS_LOGIN = 'SUCCESS_LOGIN' |
||||||
|
export const FAILED_LOGIN = 'FAILED_LOGIN' |
||||||
|
@ -0,0 +1,3 @@ |
|||||||
|
|
||||||
|
export const URL = process.env.API_URL || '//localhost:8000' |
||||||
|
export const LOGIN = '/api-token-auth/' |
@ -1,14 +1,29 @@ |
|||||||
import React from 'react' |
import React from 'react' |
||||||
import { Link } from 'react-router-dom' |
import { Link } from 'react-router-dom' |
||||||
|
import { connect } from 'react-redux' |
||||||
|
import { getToken, loggedIn } from '../reducers/auth' |
||||||
|
import { fetchAuth } from '../actions' |
||||||
|
|
||||||
const Main = (props) => ( |
const Gone = (props) => ( |
||||||
<div> |
<div> |
||||||
Gone { props.match.params.id } |
Gone { props.match.params.id } |
||||||
|
|
||||||
<hr /> |
<hr /> |
||||||
<Link to={`/`}>Main</Link> |
<Link to={`/`}>Main</Link> |
||||||
|
|
||||||
|
<hr /> |
||||||
|
{props.loggedIn ? 'Logged in': 'Nah anonymous'} |
||||||
|
<hr /> |
||||||
|
|
||||||
|
<button onClick={_ => props.fetchAuth("user", "passwd")}>Login</button> |
||||||
</div> |
</div> |
||||||
) |
) |
||||||
|
|
||||||
|
|
||||||
export default Main |
const mapStateToProps = state => ({ |
||||||
|
token: getToken(state.auth) |
||||||
|
}) |
||||||
|
export default connect( |
||||||
|
mapStateToProps, |
||||||
|
{ loggedIn, fetchAuth } |
||||||
|
)(Gone) |
||||||
|
@ -0,0 +1,40 @@ |
|||||||
|
import { |
||||||
|
SET_TOKEN, REQUEST_LOGIN, SUCCESS_LOGIN, FAILED_LOGIN, |
||||||
|
} from '../constants/ActionTypes' |
||||||
|
|
||||||
|
|
||||||
|
const tokenInitialState = { |
||||||
|
token: null, |
||||||
|
fetching: false, |
||||||
|
} |
||||||
|
const token = (state = tokenInitialState, action) => { |
||||||
|
switch(action.type) { |
||||||
|
case REQUEST_LOGIN: |
||||||
|
return { |
||||||
|
token: null, |
||||||
|
fetching: true, |
||||||
|
} |
||||||
|
case SUCCESS_LOGIN: |
||||||
|
return { |
||||||
|
token: action.body.token, |
||||||
|
fetching: false, |
||||||
|
} |
||||||
|
case FAILED_LOGIN: |
||||||
|
return { |
||||||
|
token: null, |
||||||
|
fetching: false, |
||||||
|
} |
||||||
|
case SET_TOKEN: |
||||||
|
return { |
||||||
|
token: action.token, |
||||||
|
fetching: false, |
||||||
|
}; |
||||||
|
default: |
||||||
|
return state; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export default token |
||||||
|
|
||||||
|
export const getToken = state => state.token |
||||||
|
export const loggedIn = state => state && state.token == null |
@ -1,6 +1,8 @@ |
|||||||
import { combineReducers } from 'redux' |
import { combineReducers } from 'redux' |
||||||
import first from './first' |
import first from './first' |
||||||
|
import auth from './auth' |
||||||
|
|
||||||
export default combineReducers({ |
export default combineReducers({ |
||||||
first |
auth, |
||||||
|
first, |
||||||
}) |
}) |
||||||
|
@ -0,0 +1,27 @@ |
|||||||
|
import thunk from 'redux-thunk' |
||||||
|
import { createStore, applyMiddleware, compose } from 'redux' |
||||||
|
import { createLogger } from 'redux-logger' |
||||||
|
import { persistReducer } from 'redux-persist' |
||||||
|
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web and AsyncStorage for react-native
|
||||||
|
|
||||||
|
import gruntApp from './reducers' |
||||||
|
|
||||||
|
const persistConfig = { |
||||||
|
key: 'root', |
||||||
|
storage, |
||||||
|
} |
||||||
|
|
||||||
|
const middleware = [ thunk ] |
||||||
|
if (process.env.NODE_ENV !== 'production') { |
||||||
|
middleware.push(createLogger()) |
||||||
|
} |
||||||
|
/* eslint-disable no-underscore-dangle */ |
||||||
|
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; |
||||||
|
const enhancer = composeEnhancers( |
||||||
|
applyMiddleware(...middleware), |
||||||
|
) |
||||||
|
const persistedReducer = persistReducer(persistConfig, gruntApp) |
||||||
|
|
||||||
|
const store = createStore(persistedReducer, enhancer) |
||||||
|
|
||||||
|
export default store |
@ -0,0 +1,12 @@ |
|||||||
|
import axios from 'axios' |
||||||
|
import store from '../store' |
||||||
|
import { URL } from '../config/Api' |
||||||
|
|
||||||
|
export const apiClient = function() { |
||||||
|
const token = store.getState().token |
||||||
|
const params = { |
||||||
|
baseURL: URL, |
||||||
|
headers: {'Authorization': 'Token ' + token} |
||||||
|
} |
||||||
|
return axios.create(params) |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
import axios from 'axios' |
||||||
|
import _ from 'lodash' |
||||||
|
import store from '../store' |
||||||
|
import { failAuth, successAuth } from '../actions' |
||||||
|
import { URL, LOGIN } from '../constants/Api' |
||||||
|
|
||||||
|
export function InvalidCredentialsException(message) { |
||||||
|
this.message = message |
||||||
|
this.name = 'InvalidCredentialsException' |
||||||
|
} |
||||||
|
|
||||||
|
export function login(username, password) { |
||||||
|
return axios |
||||||
|
.post(URL + LOGIN, { |
||||||
|
username, |
||||||
|
password |
||||||
|
}) |
||||||
|
.then(function (response) { |
||||||
|
store.dispatch(successAuth(response.data)) |
||||||
|
}) |
||||||
|
.catch(function (error) { |
||||||
|
store.dispatch(failAuth(error)) |
||||||
|
// raise different exception if due to invalid credentials
|
||||||
|
if (_.get(error, 'response.status') === 400) { |
||||||
|
throw new InvalidCredentialsException(error) |
||||||
|
} |
||||||
|
throw error |
||||||
|
}) |
||||||
|
} |
Loading…
Reference in new issue