authentication log in form with jwt and react - reactjs

I have made and fetched a Login form with JWT and react. I managed to fetched the data for the username and password and everything works perfectly but then I want to redirect the user to a new page when he clicks on submit and I have no idea how to do that. I'm also using react router. Any help will be welcome
import React, { Component } from "react";
import axios from "axios";
export default class Login extends Component {
constructor(props) {
super(props);
this.state = {
username: "test",
password: "test",
}
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value,
})
}
login = () => {
const {username, password} = this.state;
axios(`/users/login`, {
method: "POST",
data: {
username,
password,
}
})
.then(response => {
localStorage.setItem('token', response.data.token);
console.log(response);
})
.catch(error => {
console.log(error)
})
}
render() {
return (
<div className="log">
<h3>Sign In</h3>
<div className="form-group">
<label>Username</label>
<input type="username" className="form-control" placeholder="Enter username" name="username" value={this.state.username} onChange={this.handleChange} />
</div>
<div className="form-group">
<label>Password</label>
<input type="password" className="form-control" placeholder="Enter password" name="password" value={this.state.password} onChange={this.handleChange} />
</div>
<div className="form-group">
<div className="custom-control custom-checkbox">
<input type="checkbox" className="custom-control-input" id="customCheck1" />
<label className="custom-control-label" htmlFor="customCheck1">Remember me</label>
</div>
</div>
<button type="submit" className="btn btn-primary btn-block" onClick={this.login}>Submit</button>
<p className="forgot-password text-right">
Forgot password?
</p>
</div>
);
}
}

import withRouter import {withRouter} from 'react-router-dom';
remove export before class Login class Login extends Component {...
export class at the end of the file: export default withRouter(Login);
and use react-router-dom:
axios(`/users/login`, {
//...
})
.then(response => {
localStorage.setItem('token', response.data.token);
console.log(response);
this.props.history.push('/url');
})
//...

Related

Signup on reactjs using axios

so i was trying to make a signup & login features on my web. My problem here is i cant post signup data to my api.
Here is the code that i make :
import React, { Component } from 'react'
import { Container } from 'react-bootstrap'
import { API_URL } from '../utils/constant';
import axios from 'axios';
import swal from 'sweetalert';
export default class Signup extends Component {
constructor(props) {
super(props);
this.state = {
};
}
handleSubmit = e => {
e.preventDefault();
const data = {
username: this.username,
password: this.password,
};
axios
.post(API_URL + "signup", data)
.then(res => {
swal({
tittle: "sukses",
text: "sukses",
icon: "success",
button: false,
})
}
).catch(error => {
console.log(error);
}
)
};
render() {
return (
<div className="signup">
<Container>
<div className="signup-page">
<form onSubmit={this.handleSubmit}>
<div class="mb-3">
<label>Username</label>
<input type="text" name="username" placeholder="username anda" class="form-control" onChange={e=> this.username = e.target.value} />
<div class="form-text"></div>
</div>
<div class="mb-3">
<label>Password</label>
<input type="password" class="form-control" onChange={e=> this.password = e.target.value}/>
</div>
<button class="btn btn-primary">Sign Up</button>
</form>
</div>
</Container>
</div>
);
}
}
My code here is not giving me any error, but the data is not post/added to my API.
i hope there is any suggestion from anyone of you because im just new into this reactjs,
this is my github link so maybe you might check it :
https://github.com/dannyambarita/Tubes_PWL/

React form submit triggers two times

I have React login form. The problem is form submit is called two times. I dont understand it. Can somebody tell me please why? Thanks a lot.
import React from "react"
import LoginErrors from "./LoginErrors"
import LoginSuccess from "./LoginSuccess"
import axios from 'axios'
import { withRouter } from "react-router-dom";
class Login extends React.Component
{
constructor(props)
{
super(props)
this.state = {
name: '',
password: '',
errors: [],
success: []
}
}
changeName = e =>
{
this.setState({name: e.target.value});
}
changePassword = e =>
{
this.setState({password: e.target.value});
}
sendData(e)
{
e.preventDefault();
this.setState({'errors': [], 'success': []});
let formData = new FormData();
formData.set('name', this.state.name);
formData.set('password', this.state.password);
axios({
method: 'POST',
url: 'http://localhost:8000/login',
data: formData,
headers: {
'Content-Type': 'text/html',
'X-Requested-With': 'XMLHttpRequest',
}
})
.then(response => {
// ? returns undefined if variable is undefined
if( response.data?.errors?.length )
{
this.setState({errors: response.data.errors})
}
if( response.data?.success?.length )
{
let data = response.data
this.props.setAccessToken(data.token)
this.props.setUserName(data.user.name)
this.props.history.push('/')
}
})
.catch(response => {
this.setState({errors: ['Login fails. Try it again later please.']})
});
}
render() {
return (
<div className="row justify-content-md-center">
<div className="col-sm-12 col-md-6">
<div id="loginForm">
<h2 className="">Login</h2>
<LoginSuccess success={this.state.success} />
<LoginErrors errors={this.state.errors} sendParentMessage={this.handleErrorsChildMessage} />
<form onSubmit={e => {this.sendData(e)}}>
<div className="form-group">
<label htmlFor="name">Name</label>
<input ref={this.email} name="name" className="form-control" type="text" onChange={this.changeName} />
</div>
<div className="form-group">
<label htmlFor="password">Heslo</label>
<input ref={this.password} name="password" className="form-control" type="password" onChange={this.changePassword} />
</div>
<div className="form-group">
<button name="sbmt" className="btn btn-primary" type="submit">Odoslať</button>
</div>
</form>
</div>
</div>
</div>
);
}
}
So the problem is in axios preflyght request which is related to the CORS policy. But How to stop it?

React props.auth.user is undifined when registering a user

In my project when I try to print the name of the user that just registered it shows undifined.
When I register a user he is redirected to the dashboard page where is name should apear but it doesn´t. But when I reload the page the name shows correctly.
The login is done similiar to register but works fine.
My component to register bidder.
import React, { Component } from "react";
import { Link, Redirect } from "react-router-dom";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import { registerBidder } from "../../actions/auth";
import { createMessage } from "../../actions/messages";
export class RegisterBidder extends Component {
state = {
email: "",
password: "",
password2: "",
first_name: "",
last_name: "",
aluno: "false"
};
static propTypes = {
registerBidder: PropTypes.func.isRequired,
isAuthenticated: PropTypes.bool
};
onSubmit = e => {
e.preventDefault();
const {
email,
password,
password2,
first_name,
last_name,
aluno
} = this.state;
if (password != password2) {
this.props.createMessage({
passwordNotMatch: "Passwords não são iguais"
});
} else {
const newUser = {
email,
first_name,
last_name,
password,
aluno
};
this.props.registerBidder(newUser);
}
};
handleChange = () => {
if (this.state.aluno == "false") {
this.setState({ aluno: "true" });
} else {
this.setState({ aluno: "false" });
}
};
onChange = e => this.setState({ [e.target.name]: e.target.value });
render() {
if (this.props.isAuthenticated && this.registerBidder) {
return <Redirect to="/dashboardBidder" />;
}
const { email, password, password2, first_name, last_name } = this.state;
return (
<div className="col-md-6 m-auto">
<div className="card card-body mt-5">
<h2 className="text-center">Register</h2>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Email</label>
<input
type="email"
className="form-control"
name="email"
onChange={this.onChange}
value={email}
/>
</div>
<div className="form-group">
<label>First Name</label>
<input
type="name"
className="form-control"
name="first_name"
onChange={this.onChange}
value={first_name}
/>
</div>
<div className="form-group">
<label>Last Name</label>
<input
type="name"
className="form-control"
name="last_name"
onChange={this.onChange}
value={last_name}
/>
</div>
<div className="form-group">
<label>Password</label>
<input
type="password"
className="form-control"
name="password"
onChange={this.onChange}
value={password}
/>
</div>
<div className="form-group">
<label>Confirm Password</label>
<input
type="password"
className="form-control"
name="password2"
onChange={this.onChange}
value={password2}
/>
</div>
<div className="react__checkbox">
<label>Aluno</label>
<input
type="checkbox"
className="react__checkbox--input"
aluno={this.state.aluno}
onChange={this.handleChange}
/>
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary">
Register
</button>
</div>
<p>
Already have an account? <Link to="/login">Login</Link>
</p>
</form>
</div>
</div>
);
}
}
const mapStateToProps = state => ({
isAuthenticated: state.auth.isAuthenticated
});
export default connect(mapStateToProps, { registerBidder, createMessage })(RegisterBidder);
My action to register.
export const registerBidder = ({
email,
first_name,
last_name,
password,
aluno
}) => dispatch => {
// Headers
const config = {
headers: {
"Content-Type": "application/json"
}
};
// Request Body
const body = JSON.stringify({
user: { email, first_name, last_name, password },
aluno: aluno
});
console.log(body);
dispatch({ type: USER_LOADING });
axios
.post("/api/auth/registar/bidder", body, config)
.then(res => {
dispatch({
type: REGISTER_SUCCESS,
payload: res.data
});
})
.catch(err => {
dispatch(returnErrors(err.response.data, err.response.status));
dispatch({
type: REGISTER_FAIL
});
});
};

I have a form component I am passing to App.js but I am getting this error

Getting this error when render the app.
SignIn(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.
SignIn.js
import React, { useState, useRef } from "react";
import axios from "axios";
import swal from "sweetalert";
import "./SignUp.css";
import image from './img/signup.jpg'
const SignIn = () => {
const [creds, setCreds] = useState({ userName: "", password: "" });
const usernameFieldRef = useRef();
const passwordFieldRef = useRef();
const changeHandler = e => {
setCreds({ ...creds, [e.target.name]: e.target.value });
};
const handleSubmit = event => {
event.preventDefault();
console.log('login');
const username = usernameFieldRef.current.value;
const password = passwordFieldRef.current.value;
axios
.post("https://foodiefun-api.herokuapp.com/api/auth/login", {
username,
password
})
.then(res => {
console.log("DATA", res.data)
localStorage.setItem('token', res.data.token)
swal(
"Welcome to Foodie Fun!",
"You are now signed in, enjoy your stay!",
"success"
);
})
.catch(err => {
console.log('LOGIN FAILED', err.response); // There was an error creating the data and logs to console
});
return (
<div class="page-content">
<div class="form-v6-content">
<div class="form-left">
<img className="form-image" style={{ linearGradient: "red, blue", opacity: ".6" }} src={image} alt="form" />
</div>
<form
onSubmit={handleSubmit}
class="form-detail"
method="post">
<h2>Register Form</h2>
<div class="form-row">
<input
ref={usernameFieldRef}
onChange={changeHandler}
// value={creds.userName}
type="text"
name="id"
id="user-name"
class="input-text"
placeholder="Enter Desired User Name"
required />
</div>
<div class="form-row">
<input
ref={passwordFieldRef}
onChange={changeHandler}
value={creds.password}
type="password"
name="password"
id="password"
class="input-text"
placeholder="Password"
required />
</div>
<div class="form-row">
<input
type="password"
name="comfirm-password"
id="comfirm-password"
class="input-text"
placeholder="Comfirm Password"
required />
</div>
<div class="form-row-last">
<input type="submit"
name="register"
class="register"
value="Register" />
</div>
</form>
</div>
</div>
)
}
}
export default SignIn
App.js
import React, { useState } from "react";
import "./App.css";
import Form from "./Components/SignIn";
import ReviewForm from "./Components/ReviewForm/ReviewForm";
import UserInfo from "./Components/userInfo";
import mockarray from "./Components/mockarray";
import Navbar from "./Components/Navbar";
import RecipeApp from "./recipes/RecipeApp";
import SignUp from "./Components/SignUp";
import SignIn from "./Components/SignIn";
const App = () => {
const [reviews, setReviews] = useState([]);
const addReview = restaurant => {
setReviews([...reviews, { ...restaurant, id: Date.now() }]);
};
return (
<div className="App">
<Navbar />
<SignUp />
<SignIn />
{/* <RecipeApp /> */}
{/* <ReviewForm /> */}
{/* <ReviewForm addReview={addReview} /> */}
{console.log(reviews)}
{/* <UserInfo data = {mockarray} /> */}
</div>
);
};
export default App;
Two forms should be rendering on the screen but when I comment in the SignIn page I get this error. A couple of people have looked at it and they both say everything is right. I'm stumped!
Your return statement is inside the handleSubmit function.
You need to return your state outside handleSubmit function :
import React, { useState, useRef } from "react";
import axios from "axios";
import swal from "sweetalert";
import "./SignUp.css";
import image from './img/signup.jpg'
const SignIn = () => {
const [creds, setCreds] = useState({ userName: "", password: "" });
const usernameFieldRef = useRef();
const passwordFieldRef = useRef();
const changeHandler = e => {
setCreds({ ...creds, [e.target.name]: e.target.value });
};
const handleSubmit = event => {
event.preventDefault();
console.log('login');
const username = usernameFieldRef.current.value;
const password = passwordFieldRef.current.value;
axios
.post("https://foodiefun-api.herokuapp.com/api/auth/login", {
username,
password
})
.then(res => {
console.log("DATA", res.data)
localStorage.setItem('token', res.data.token)
swal(
"Welcome to Foodie Fun!",
"You are now signed in, enjoy your stay!",
"success"
);
})
.catch(err => {
console.log('LOGIN FAILED', err.response); // There was an error creating the data and logs to console
});
}
return (
<div class="page-content">
<div class="form-v6-content">
<div class="form-left">
<img className="form-image" style={{ linearGradient: "red, blue", opacity: ".6" }} src={image} alt="form" />
</div>
<form
onSubmit={handleSubmit}
class="form-detail"
method="post">
<h2>Register Form</h2>
<div class="form-row">
<input
ref={usernameFieldRef}
onChange={changeHandler}
// value={creds.userName}
type="text"
name="id"
id="user-name"
class="input-text"
placeholder="Enter Desired User Name"
required />
</div>
<div class="form-row">
<input
ref={passwordFieldRef}
onChange={changeHandler}
value={creds.password}
type="password"
name="password"
id="password"
class="input-text"
placeholder="Password"
required />
</div>
<div class="form-row">
<input
type="password"
name="comfirm-password"
id="comfirm-password"
class="input-text"
placeholder="Comfirm Password"
required />
</div>
<div class="form-row-last">
<input type="submit"
name="register"
class="register"
value="Register" />
</div>
</form>
</div>
</div>
)
}
export default SignIn
Working code : https://codesandbox.io/s/divine-field-kkfd6
Not sure if it's a typo on the code of your question or in your acctual code but the return is inside handleSubmit.
import React, { useState, useRef } from 'react'
import axios from 'axios'
import swal from 'sweetalert'
import './SignUp.css'
import image from './img/signup.jpg'
const SignIn = () => {
const [creds, setCreds] = useState({ userName: '', password: '' })
const usernameFieldRef = useRef()
const passwordFieldRef = useRef()
const changeHandler = e => {
setCreds({ ...creds, [e.target.name]: e.target.value })
}
const handleSubmit = event => {
event.preventDefault()
console.log('login')
const username = usernameFieldRef.current.value
const password = passwordFieldRef.current.value
axios
.post('https://foodiefun-api.herokuapp.com/api/auth/login', {
username,
password
})
.then(res => {
console.log('DATA', res.data)
localStorage.setItem('token', res.data.token)
swal(
'Welcome to Foodie Fun!',
'You are now signed in, enjoy your stay!',
'success'
)
})
.catch(err => {
console.log('LOGIN FAILED', err.response) // There was an error creating the data and logs to console
})
}
return (
<div className="page-content">
<div className="form-v6-content">
<div className="form-left">
<img
className="form-image"
style={{ linearGradient: 'red, blue', opacity: '.6' }}
src={image}
alt="form"
/>
</div>
<form onSubmit={handleSubmit} className="form-detail" method="post">
<h2>Register Form</h2>
<div className="form-row">
<input
ref={usernameFieldRef}
onChange={changeHandler}
// value={creds.userName}
type="text"
name="id"
id="user-name"
className="input-text"
placeholder="Enter Desired User Name"
required
/>
</div>
<div className="form-row">
<input
ref={passwordFieldRef}
onChange={changeHandler}
value={creds.password}
type="password"
name="password"
id="password"
className="input-text"
placeholder="Password"
required
/>
</div>
<div className="form-row">
<input
type="password"
name="comfirm-password"
id="comfirm-password"
className="input-text"
placeholder="Comfirm Password"
required
/>
</div>
<div className="form-row-last">
<input
type="submit"
name="register"
className="register"
value="Register"
/>
</div>
</form>
</div>
</div>
)
}
export default SignIn

Laravel React MySQL Routing Issue

I am trying to make it so that I can register a user but I am getting a 404 error, assuming that means that react is unable to find the route established by the api.php file, is there anything else that I am missing? I have already set it in the package.json file that the proxy is set to "localhost:8000" (the port I chose to use for laravel's backend stuff). I am confused on why it's not hitting this route upon submitting. I feel like I'm close but I am new to using php as the backend so any insight would be helpful.
I am also creating something where the user is able to play music on the app, so there is a route for that labeled "shop", and that does not work for the sole reason that I have not set that route up (also gives a 404 error).
Below are my api routes that I am trying to get react to detect
<?php
Route::post('register','UserController#register');
Route::post('login','UserController#login');
Route::post('profile','UserController#getAuthenticatedUser');
Route::middleware('auth:api')->get('/user', function(Request $request){
return $request->user();
});
?>
And this is the React portion of my registration file.
import React, { Component } from 'react';
import { register } from './UserFunctions';
class Register extends Component {
constructor() {
super()
this.state = {
first_name: '',
last_name: '',
email: '',
password: '',
errors: {},
}
this.onChange = this.onChange.bind(this)
this.onSubmit = this.onSubmit.bind(this)
}
onChange(e) {
this.setState({ [e.target.name]: e.target.value })
}
onSubmit(e) {
e.preventDefault()
const newUser = {
name: this.state.first_name + ' ' + this.state.last_name,
email: this.state.email,
password: this.state.password
}
register(newUser).then(res => {
if (res) {
this.props.history.push('/login')
}
})
}
render() {
return (
<div className="container">
<div className="row">
<div className="col-md-6 mt-5 mx auto">
<form noValidate onSubmit={this.onSubmit}>
<h1 className="h3 mb-3 font-wieght-normal">
Register
</h1>
<div className="form-group">
<label htmlFor="first_name">First Name</label>
<input type="text" className="form-control" name="first_name" placeholder="Enter First Name" value={this.state.first_name} onChange={this.onChange} />
<label htmlFor="last_name">Last Name</label>
<input type="text" className="form-control" name="last_name" placeholder="Enter Last Name" value={this.state.last_name} onChange={this.onChange} />
<label htmlFor="email">Email Address</label><br />
<input type="email" className="form-control" name="email" placeholder="Enter Email" value={this.state.email} onChange={this.onChange} />
<br />
<label htmlFor="password">Desired Password</label><br />
<input type="password" className="form-control" name="password" placeholder="Enter Password" value={this.state.password} onChange={this.onChange} />
</div>
<button type="submit" className="btn btn-lg btn-primary btn-block">Register</button>
</form>
</div>
</div>
</div>
)
}
}
export default Register
I have those post routes defined, but when I press submit within my register form, I get a 404 error saying that it can't find this route.
Can you show me your
import { register } from './UserFunctions';
file so that I can see the url path defined.
Assuming this route is inside your routes/api.php
Route::group(['middleware' => 'api', 'prefix' => 'v1'], function(){
Route::post('register', 'RegisterController#index');
});
and in JS file
import axios from 'axios'
export const register = newUser => {
return axios
.post('api/v1/register', newUser,
{
headers: { 'Content-Type': 'application/json' }
})
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
}

Resources