React JS and PHP Restful API User Authentication for Login and Signup.
Wall Script
MailxEngine
Follow Me:
Monday, October 23, 2017

React JS and PHP Restful API User Authentication for Login and Signup.

Here is the continued article on my previous post for creating a welcome with login and logout using ReactJS. Today’s post explains how to implement login authentication system for your React JS applications. It will show you how to log in with a user and store the user session, so it deals with token-based authentication. Since we are using token-based authentication, it protects if any unauthorized request is made and notices for a new login if required. This makes your application’s authentication to be more secure compared with any other authentication system. Every user details will be stored in an external database and a PHP based API is used in the backend for handling this authentication. Hope you’ll find it more easily using this as your authentication system in your ReactJS projects. Let’s look into the live demo and follow the below code.

React JS and PHP Restful API User Authentication for Login and Signup.


Live Demo


Video Tutorial
ReactJS User Restful Authentication for Login and Signup


Database Design
To build the user feed system, you have to create two tables such as Users and Feed. You can check my previous tutorials for creating token-based API system.

Users
User table contains all the users registration details.
CREATE TABLE users(
user_id int AUTO_INCREMENT PRIMARY KEY,
username varchar(50),
password varchar(300),
name varchar(200),
email varchar(300));

Feed
This table contains user daily updates.
CREATE TABLE feed(
feed_id int PRIMARY KEY AUTO_INCREMENT,
feed text,
user_id_fk int
);

Download PHP Restul Project
$git clone https://github.com/srinivastamada/PHP-Slim-Restful.git

welcome.js
As explain in previous tutorial, just include Login and Signup component links.
import React, {Component} from 'react';
import './Welcome.css';

class Welcome extends Component {
render() {
return (
<div className="row " id="Body">
<div className="medium-12 columns">
<h2 id="welcomeText">Make people fall in love with your ideas</h2>
<a href="/login" className="button">Login</a>
<a href="/signup" className="button success">Signup</a>
</div>
</div>
);
}
}
export default Welcome;


Step 1 - Login.js
Designing Login component, here just include HTML for login form. Created constructor function with super properties for intitiating global this
import React, {Component} from 'react';
import './Login.css';
class Login extends Component {
constructor(){
super();
};
}

render() {
return (
<div className="row" id="Body">
<div className="medium-5 columns left">
<h4>Login</h4>
<label>Username</label>
<input type="text" name="username" placeholder="Username" />
<label>Password</label>
<input type="password" name="password" placeholder="Password" />
<input type="submit" className="button success" value="Login" />
<a href="/signup">Registration</a>
</div>
</div>
);
}
}
export default Login;

Step 2 - Login.js
In constructor function defined the state object for changing input fields. Login() function will communicate with RESTful API and onChange function set the state value based on the user input value.
import React, {Component} from 'react';
import './Login.css';
class Login extends Component {

constructor(){
super();
this.state = {
username: '',
password: '',
redirectToReferrer: false
};
this.login = this.login.bind(this);
this.onChange = this.onChange.bind(this);
}
login() {
//API Action Here
}

onChange(e){
this.setState({[e.target.name]:e.target.value});
}

render() {
return (
<div className="row" id="Body">
<div className="medium-5 columns left">
<h4>Login</h4>
<label>Username</label>
<input type="text" name="username" onChange={this.onChange}/>
<label>Password</label>
<input type="password" name="password" onChange={this.onChange}/>
<input type="submit" value="Login" onClick={this.login}/>
<a href="/signup">Registration</a>
</div>
</div>
);
}
}
export default Login;


PostData.js
In src/service create an export class for fetching RESTful calls and returns Promise.
export function PostData(type, userData) {
let BaseURL = 'https://api.thewallscript.com/restful/';
//let BaseURL = 'http://localhost/PHP-Slim-Restful/api/';
return new Promise((resolve, reject) =>{
fetch(BaseURL+type, {
method: 'POST',
body: JSON.stringify(userData)
})
.then((response) => response.json())
.then((res) => {
resolve(res);
})
.catch((error) => {
reject(error);
});
});
}


Final Login.js
Imported Redirect and PostData components. Login function set the state redirtion value to true, one the API is succesful. Based on the state.redirection value, the page will redirect to the home page.
import React, {Component} from 'react';
import {Redirect} from 'react-router-dom';
import {PostData} from '../../services/PostData';
import './Login.css';
class Login extends Component {
constructor(){
super();
this.state = {
username: '',
password: '',
redirectToReferrer: false
};
this.login = this.login.bind(this);
this.onChange = this.onChange.bind(this);
}

login() {
if(this.state.username && this.state.password){
PostData('login',this.state).then((result) => {
let responseJson = result;
if(responseJson.userData){
sessionStorage.setItem('userData',JSON.stringify(responseJson));
this.setState({redirectToReferrer: true});
}
});
}
}

onChange(e){
this.setState({[e.target.name]:e.target.value});
}
render() {

if (this.state.redirectToReferrer || sessionStorage.getItem('userData')){
return (<Redirect to={'/home'}/>)
}

return (
<div className="row" id="Body">
<div className="medium-5 columns left">
<h4>Login</h4>
<label>Username</label>
<input type="text" name="username" onChange={this.onChange}/>
<label>Password</label>
<input type="password" name="password" onChange={this.onChange}/>
<input type="submit" value="Login" onClick={this.login}/>
<a href="/signup">Registration</a>
</div>
</div>
);
}
}
export default Login;

PHP
This code contains login ang sigup function with PDO MySQL connetion and it works with Slim framework. Download this project from GitHub.
<?php
require 'config.php';
require 'Slim/Slim.php';

\Slim\Slim::registerAutoloader();
$app = new \Slim\Slim();

$app->post('/login','login'); /* User login */
$app->post('/signup','signup'); /* User Signup */
$app->post('/feed','feed'); /* User Feeds */
$app->post('/feedUpdate','feedUpdate'); /* User Feeds */
$app->post('/feedDelete','feedDelete'); /* User Feeds */
//$app->post('/userDetails','userDetails'); /* User Details */

$app->run();

/************************* USER LOGIN *************************************/
/* ### User login ### */
function login() {
    $request = \Slim\Slim::getInstance()->request();
    $data = json_decode($request->getBody());
    try {
       $db = getDB();
       $userData ='';
       $sql = "SELECT user_id, name, email, username FROM users WHERE (username=:username or email=:username) and password=:password ";
      $stmt = $db->prepare($sql);
      $stmt->bindParam("username", $data->username, PDO::PARAM_STR);
      $password=hash('sha256',$data->password);
      $stmt->bindParam("password", $password, PDO::PARAM_STR);
      $stmt->execute();
      $mainCount=$stmt->rowCount();
      $userData = $stmt->fetch(PDO::FETCH_OBJ);
if(!empty($userData))
{
     $user_id=$userData->user_id;
     $userData->token = apiToken($user_id);
}
    $db = null;
if($userData){
   $userData = json_encode($userData);
   echo '{"userData": ' .$userData . '}';
} else {
   echo '{"error":{"text":"Bad request wrong username and password"}}';
}

}
catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}


/* ### User registration ### */
function signup() {
   $request = \Slim\Slim::getInstance()->request();   
   $data = json_decode($request->getBody());
   $email=$data->email;
   $name=$data->name;
   $username=$data->username;
   $password=$data->password;
   try {
       $username_check = preg_match('~^[A-Za-z0-9_]{3,20}$~i', $username);
       $email_check = preg_match('~^[a-zA-Z0-9._-][email protected][a-zA-Z0-9._-]+\.([a-zA-Z]{2,4})$~i', $email);
      $password_check = preg_match('~^[[email protected]#$%^&*()_]{6,20}$~i', $password);
     
    if (strlen(trim($username))>0 && strlen(trim($password))>0 && strlen(trim($email))>0 && $email_check>0 && $username_check>0 && $password_check>0)
   {
    $db = getDB();
    $userData = '';
    $sql = "SELECT user_id FROM users WHERE username=:username or email=:email";
    $stmt = $db->prepare($sql);
    $stmt->bindParam("username", $username,PDO::PARAM_STR);
    $stmt->bindParam("email", $email,PDO::PARAM_STR);
    $stmt->execute();
   $mainCount=$stmt->rowCount();
   $created=time();
   if($mainCount==0)
  {
    /*Inserting user values*/
     $sql1="INSERT INTO users(username,password,email,name)VALUES(:username,:password,:email,:name)";
      $stmt1 = $db->prepare($sql1);
      $stmt1->bindParam("username", $username,PDO::PARAM_STR);
      $password=hash('sha256',$data->password);
      $stmt1->bindParam("password", $password,PDO::PARAM_STR);
      $stmt1->bindParam("email", $email,PDO::PARAM_STR);
      $stmt1->bindParam("name", $name,PDO::PARAM_STR);
      $stmt1->execute();
      $userData=internalUserDetails($email);
      }
      $db = null;

if($userData){
      $userData = json_encode($userData);
      echo '{"userData": ' .$userData . '}';
} else {
      echo '{"error":{"text":"Enter valid data"}}';
}

}
else{
      echo '{"error":{"text":"Enter valid data"}}';
}
}
catch(PDOException $e) {
      echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
?>

Was this article helpful?
Thanks! Your feedback helps us to improve 9lessons.info


3 comments:

Make in India