Search code examples
phpiossecurity

Prevent users from generating authentication tokens


I have an API with an endpoint like so POST http://localhost:8080/api/authenticate. Go to that and you POST an email and password and you get an authentication token. Seems solid so far.

Now what about registering. I'd need to create some sort of request token, but how would I prevent random users from creating a request token through the API? I was thinking of generating the token from http://localhost:8080/api/request then returning it and checking if it existed when a user went to register. The thing is anybody can go to http://localhost:8080/api/request, even if they're not planning on registering. Any idea?


Solution

  • Authenticate the user before you generate an auth-token(cookie)... so write a query to pull the id from the user table where email/password matches... so only if the query returns an id then you know the user exists and is "authenticated", therefore you can now generate a auth-token(cookie) setting it to the usrid...

    However setting the cookie to the usrid is not a good practice! since anyone on the client-side could easily set/pass a cookie with a number in a POST request... you need implement some mechanism of encryption to generate a "session" which you can then use as a unique hack-proof user identifier.

    I wrote a simple encryption function in the code below which you can use.

    <?php
    //CHECK IF POST DATA IS EMPTY IF SO KILL THE SCRIPT
    if(empty($_POST['email']) || empty($_POST['pass'])){
        //echo("error msg"); 
        die();
    }
    $mysqli = new mysqli('localhost', 'root', 'root', 'accounts');
    $pass = md5($_POST['pass']);
    
    $query = "SELECT `id` FROM `users` WHERE `email` = '" 
        . $mysqli->real_escape_string($_POST['email']) 
        . "' AND `password` = '" 
        . $mysqli->real_escape_string($_POST['pass']) . "'"; 
    
    //INITIATE DB REQUEST
    $result = $mysqli->query($query);
    //SELECT ID(OBJ) FROM THE RESULT OBJECT
    $usrid = $result->fetch_object()->id;
    //IF $USRID IS TRUE... USER DOES EXIST (AUTHENTICATED) 
    if ($usrid) {
        $sesh = create_session($usrid);
        update_session($usrid, $sesh);
        setcookie("usersesh", $sesh, 0,"/");
    } else {
        //echo("error msg");
    }
    
    $result->free();
    $mysqli->close();
    function create_session($usrid) {
        $time = microtime();
        $hash = substr($time, 2, 3);
        $key = $usrid * $hash;
        $sesh = md5($key);
        return $sesh;   
    }
    function update_session($usrid, $sesh) {
        $mysqli = new mysqli('localhost', 'root', 'root', 'accounts');
        $query = "UPDATE `users` SET `session` = '" 
            . $mysqli->real_escape_string($sesh) . "' WHERE `id` = '" 
            . $mysqli->real_escape_string($usrid) . "'"; 
        $mysqli->query($query);
        $mysqli->close();   
    }
    ?>