Search code examples
phpsecurityslimrestful-authentication

implementing access control authentication with php Slim framework


I am working in building a restful api using php & slim for my app backend and also we have a web version but my team use pure php with the web suit , we work separately . it is just the first time that i have the backend responsibility I have a miss understanding about how i can handle the authentication in a secure and professional way i have read this article but i need a detailed way how to implement it in php & slim and extend it to the web team so to use the same authentication technic .

this is how the log in / sign up code that i have used : help me to improve it :

    $app->post('/api/create_user', function( $request , $response , $args ){

require('../config.php');


$email = $_POST['email'];
$qry= "select * from user where email ='". $email."'";

$result=$mysqli->query($qry);

if(mysqli_num_rows($result)>0){

$user = new stdClass();
$user->status=0;
$user->error=" the email is registered ";
$result = new stdClass();
$result->result=$user;


}

else {


$password = md5($_POST['password']);
$image=$_FILES['image']['name'];
$email=$_POST['email'] ;
$nickname =$_POST['nickname'];
$birthDay=$_POST['birthdate'];

$insert_req="INSERT INTO user VALUES ('', '$email', '$password','$nickname')";

$insert_user_result=$mysqli->query($insert_req);    

if ($insert_user_result) {

$user = new stdClass();
$user->status=1;
$result = new stdClass();
$result->result=$user;}

else {$user = new stdClass();
$user->status=2;
$user->error=mysql_error();
$result = new stdClass();
$result->result=$user;}

}

if (isset($result)){
    header('Content-type: application/json');
echo json_encode($result);}

});


?>




    <?php
$app->post('/api/login', function( $request , $response , $args ){
require('../config.php');

$email =$_POST['email'];
$password = md5($_POST['password']);

$findemail_qry= "select user_id from user where email ='". $email."'";
$findemail_result =$mysqli->query($findemail_qry);

if(mysqli_num_rows($findemail_result)>0)
{
$login_qry="select user_id from user where email ='". $email."'AND password ='".$password."'";
$login_result =$mysqli->query($login_qry);
if(mysqli_num_rows($login_result)>0)
{
 $data =mysqli_fetch_assoc ($login_result);

$user_id=$data['user_id']; 
$user = new stdClass();
$user->status=1;
$user->user_id=$user_id;
$result = new stdClass();
$result->result=$user;}
           else
{$user = new stdClass();
$user->status=2;
$user->error="wrong password";
$result = new stdClass();
$result->result=$user; }
       }
           else 
{$user = new stdClass();
$user->status=0;
$user->error=" this email not registered ";
$result = new stdClass();
$result->result=$user;}


if (isset($result)){
    header('Content-type: application/json');
echo json_encode($result);
}

       });
?>

Solution

  • You can use JWT in your slim application as your authntication layer for Your API

    You can use this library to implement it Slim JWT

    In a simple way you can use something like this

    Try to use Basic authorization to send user name and password Then You will generate a new JWT Token ,That will used in all others API

    <?php
    
    use \Firebase\JWT\JWT;
    use \Slim\Middleware\HttpBasicAuthentication\AuthenticatorInterface;
    
    require '../vendor/autoload.php';
    
    $app = new \Slim\App;
    
    class RandomAuthenticator implements AuthenticatorInterface {
       public function __invoke(array $arguments) {
    
        //validation for user and password 
         $Password=$arguments['password'];
          $user=$arguments['user'];
    if(($Password=="admin") &&($user=="admin") ){
    return true;
    }  
    else{
    
        return false ;
    
        }
    
    }}
    
    //add  http basic middleware for login route  
    $app->add(new \Slim\Middleware\HttpBasicAuthentication([
        "path" => "/login",
         "realm" => "Protected",
        "authenticator" => new RandomAuthenticator()
    
    ]));
    
    
    $app->post("/login", function ($request, $response, $arguments) {
    //generate JWT token 
        $now = new DateTime();
        $future = new DateTime("now +20 minutes");
        $server = $request->getServerParams();
    
        $payload = [
            "iat" => $now->getTimeStamp(),
            "exp" => $future->getTimeStamp(),
            "sub" => $server["PHP_AUTH_USER"],
        ];
        $secret = "TOURSECERTKEY";
        $token = JWT::encode($payload, $secret, "HS512");
        $data["status"] = "ok";
        $data["token"] = $token;
    
        return $response->withStatus(201)
            ->withHeader("Content-Type", "application/json")
            ->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
    });
    //Add jWT token Authorization middleware for all API  
    $app->add(new \Slim\Middleware\JwtAuthentication([
         "path" => ["/"],
        "passthrough" => ["/login"],
        "secret" => "TOURSECERTKEY",
        "error" => function ($request, $response, $arguments) {
            $data["status"] = "error";
            $data["message"] = $arguments["message"];
            return $response
                ->withHeader("Content-Type", "application/json")
                ->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
        }
    ]));