username/password mismatch
redux logger shows rejected action
login success, token obtained
redux logger shows fulfilled action
#powershell
#django rest framework enable cors
pip install djangorestframework
pip install django-cors-headers
------------------------------------
#django settings
INSTALLED_APPS = (
...
'rest_framework',
'rest_framework.authtoken',
'corsheaders',
)
MIDDLEWARE_CLASSES = (
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
)
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES':(
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',
),
}
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
-------------------------------------------
#django url
from django.urls import path
from rest_framework.authtoken import views
urlpatterns = [
path('api-token-auth/', views.obtain_auth_token, name='AuthToken'),
]
-----------------------------------
//react directories
#django rest framework enable cors
pip install djangorestframework
pip install django-cors-headers
------------------------------------
#django settings
INSTALLED_APPS = (
...
'rest_framework',
'rest_framework.authtoken',
'corsheaders',
)
MIDDLEWARE_CLASSES = (
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
)
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES':(
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',
),
}
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
-------------------------------------------
#django url
from django.urls import path
from rest_framework.authtoken import views
urlpatterns = [
path('api-token-auth/', views.obtain_auth_token, name='AuthToken'),
]
-----------------------------------
//react directories
//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { BrowserRouter } from 'react-router-dom'
import 'bootstrap/dist/css/bootstrap.min.css';
import 'antd/dist/antd.css';
import { Provider } from "react-redux";
import store from "./redux/store";
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>, document.getElementById('root'));
serviceWorker.unregister();
--------------------------------------------
//app.js
import React, { Component } from 'react';
import './App.css';
import Header from './partials/header';
import Body from './partials/body';
class App extends Component {
render() {
return (
<div>
<Header />
<Body />
</div>
);
}
}
export default App;
---------------------------------------------
//partials/body.js
import React, { Component } from 'react';
import '../App.css';
import { Switch, Route } from 'react-router-dom';
import Albums from '../pages/albums';
import Login from '../pages/login';
export default class Body extends Component {
render() {
return (
<main className='Body-Background'>
<Switch>
<Route exact path='/' component={Albums} />
<Route exact path='/login/' component={Login} />
</Switch>
</main>
);
}
}
-----------------------------------------------
//pages/login.js
import React, { Component } from 'react';
import '../App.css';
import { Input } from 'antd';
import { FaUser, FaBarcode } from "react-icons/fa";
import { Button } from 'reactstrap';
import axios from 'axios';
import { connect } from 'react-redux';
import { fetchToken } from '../redux/actions/loginAction'
class Login extends Component {
constructor(props) {
super(props);
this.state = {
username: '',
password: '',
};
}
inputChange = (e, p) => {
this.setState({ [p]: e.target.value });
}
formSubmit = (e) => {
e.preventDefault();
this.props.dispatch(fetchToken(this.state.username, this.state.password))
}
render() {
return (
<form style={{ marginLeft: '10px', width: '300px' }}
onSubmit={(e) => this.formSubmit(e)}>
<legend>Login</legend>
<hr />
<p style={{ color: 'red' }}>{this.props.error}</p>
<p style={{ color: 'blue' }}>Token: {this.props.token}</p>
<Input placeholder="username" required='required'
prefix={<FaUser style={{ color: 'rgba(0,0,0,.25)' }} />}
onChange={(e) => this.inputChange(e, 'username')}
style={{ marginTop: '5px' }}
/>
<Input placeholder="password" required='required' type='password'
prefix={<FaBarcode style={{ color: 'rgba(0,0,0,.25)' }} />}
onChange={(e) => this.inputChange(e, 'password')}
style={{ marginTop: '15px' }}
/>
<Button color="success" type='submit' size='sm'
style={{ marginTop: '15px' }}
>Submit</Button>
</form>
);
}
}
export default connect(
(store) => {
return {
username: store.login.username,
token: store.login.token,
loggingin: store.login.fetching,
loggedin: store.login.fetched,
error: store.login.error
};
}
)(Login);
---------------------------------------------
//redux/actions/loginAction
import axios from 'axios';
export function fetchToken(username, password) {
return {
type: "fetch_token",
payload: axios({
method: 'post',
url: 'http://127.0.0.1:8000/api/api-token-auth/',
data: {
'username': username,
"password": password
},
})
}
}
--------------------------------------
//redux/reducers/index
import { combineReducers } from 'redux';
import login from "./loginReduder";
export default combineReducers(
{
login
})
-----------------------------
//redux/reducers/loginReducer
export default function reducer(
state = {
username: '',
token: '',
fetching: false,
fetched: false,
error: ''
},
action
) {
switch (action.type) {
case "fetch_token_PENDING": {
return { ...state, fetching: true, fetched: false }
}
case "fetch_token_FULFILLED": {
return {
...state,
fetching: false,
fetched: true,
token: action.payload.data.token,
error: ''
}
}
case "fetch_token_REJECTED": {
return {
...state,
fetching: false,
fetched: false,
error: action.payload.toString()
}
}
default:
break;
}
return state;
}
---------------------------------
//redux/store
import { applyMiddleware, createStore } from 'redux';
import logger from 'redux-logger';
import thunk from 'redux-thunk';
import promise from 'redux-promise-middleware';
import reducer from "./reducers";
const middleware = applyMiddleware(promise, thunk, logger);
export default createStore(reducer, middleware);
reference:
http://chuanshuoge2.blogspot.com/2019/05/django-40-django-react.html
No comments:
Post a Comment