<?php
define("DB_HOST", "localhost");
define("DB_USER", "usr_nombre_usuario_bd");
define("DB_PASSWORD", "password_usr_nombre_usuario_bd");
define("DB_DATABASE", "db_nombre_base_de_datos");
?>
El siguiente de los archivos se llamará DB_Connect.php y simplemente es el encargado de conectar a la base de datos.
<?php
class DB_Connect {
function __construct() {
}
function __destruct() {
$this->close();
}
public function connect() {
require_once 'config.php';
$con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
mysql_select_db(DB_DATABASE);
return $con;
}
public function close() {
mysql_close();
}
}
?>
El tercero de los archivos se llamará DB_Functions.php y en el se harán las conexiones a la base de datos.
<?php
class DB_Functions {
private $db;
function __construct() {
require_once 'DB_Connect.php';
$this->db = new DB_Connect();
$this->db->connect();
}
function __destruct() {
}
/**
* Guardamos nuevos usuarios
* Devolvemos detalle del usuario
*/
public function storeUser($name, $email, $password) {
$uuid = uniqid('', true);
$hash = $this->hashSSHA($password);
$encrypted_password = $hash["encrypted"]; // password encriptada
$salt = $hash["salt"]; // salt
$result = mysql_query("INSERT INTO users(unique_id, name, email, encrypted_password, salt, created_at) VALUES('$uuid', '$name', '$email', '$encrypted_password', '$salt', NOW())");
// comprobamos que la query se ejecutó correctamente
if ($result) {
// obtener detalle del usuario
$uid = mysql_insert_id();
$result = mysql_query("SELECT * FROM users WHERE uid = $uid");
// devolvemos detalle del usuario
return mysql_fetch_array($result);
} else {
return false;
}
}
/**
* Obtenemos usuario por email y contraseña
*/
public function getUserByEmailAndPassword($email, $password) {
$result = mysql_query("SELECT * FROM users WHERE email = '$email'") or die(mysql_error());
// verificamos el resultado de la query
$no_of_rows = mysql_num_rows($result);
if ($no_of_rows > 0) {
$result = mysql_fetch_array($result);
$salt = $result['salt'];
$encrypted_password = $result['encrypted_password'];
$hash = $this->checkhashSSHA($salt, $password);
if ($encrypted_password == $hash) {
// Se ha autenticado al usuario correctamente
return $result;
}
} else {
// usuario no encontrado
return false;
}
}
/**
* Comprobamos si el usuario existe o no
*/
public function isUserExisted($email) {
$result = mysql_query("SELECT email from users WHERE email = '$email'");
$no_of_rows = mysql_num_rows($result);
if ($no_of_rows > 0) {
// usuario existe
return true;
} else {
// usuario no existe
return false;
}
}
/**
* Encriptamos la password
* devolvemos el salt y la password encriptada
*/
public function hashSSHA($password) {
$salt = sha1(rand());
$salt = substr($salt, 0, 10);
$encrypted = base64_encode(sha1($password . $salt, true) . $salt);
$hash = array("salt" => $salt, "encrypted" => $encrypted);
return $hash;
}
/**
* Desencriptamos la password
* Devolvemos una hash string
*/
public function checkhashSSHA($salt, $password) {
$hash = base64_encode(sha1($password . $salt, true) . $salt);
return $hash;
}
}
?>
En este se ha creado una función para insertar el usuario que al crearlo devuelve un array con los nuevos datos, también se puede buscar por email y contraseña o comprobar si el usuario ya existe.
El cuarto de los archivos se llamará index.php, a este es al que llegarán todas las peticiones de login y registro.
<?php
/**
* Comprobamos la petición POST
*/
if (isset($_POST['tag']) && $_POST['tag'] != '') {
// obtenemos tag
$tag = $_POST['tag'];
require_once 'DB_Functions.php';
$db = new DB_Functions();
// Empezamos a preparar la respuesta en forma de Array que luego convertiremos en un json
$response = array("tag" => $tag, "success" => 0, "error" => 0);
// evaluamos tag
if ($tag == 'login') {
// chequeamos el login
$email = $_POST['email'];
$password = $_POST['password'];
// obtenemos y comprobamos el usuario por email y password
$user = $db->getUserByEmailAndPassword($email, $password);
if ($user != false) {
// usuario encontrado
// marcamos el json como correcto con success = 1
$response["success"] = 1;
$response["uid"] = $user["unique_id"];
$response["user"]["name"] = $user["name"];
$response["user"]["email"] = $user["email"];
$response["user"]["created_at"] = $user["created_at"];
$response["user"]["updated_at"] = $user["updated_at"];
echo json_encode($response);
} else {
// usuario no encontrado
// marcamos el json con error = 1
$response["error"] = 1;
$response["error_msg"] = "Email o password incorrecto!";
echo json_encode($response);
}
} else if ($tag == 'register') {
// Registrar nuevo usuario
$name = $_POST['name'];
$email = $_POST['email'];
$password = $_POST['password'];
// comprobamos si ya existe el usuario
if ($db->isUserExisted($email)) {
// usuario ya existe - marcamos error 2
$response["error"] = 2;
$response["error_msg"] = "Usuario ya existe";
echo json_encode($response);
} else {
// guardamos el nuevo usuario
$user = $db->storeUser($name, $email, $password);
if ($user) {
// usuario guardado correctamente
$response["success"] = 1;
$response["uid"] = $user["unique_id"];
$response["user"]["name"] = $user["name"];
$response["user"]["email"] = $user["email"];
$response["user"]["created_at"] = $user["created_at"];
$response["user"]["updated_at"] = $user["updated_at"];
echo json_encode($response);
} else {
// fallo en la inserción del usuario
$response["error"] = 1;
$response["error_msg"] = "Ocurrió un error durante el registro";
echo json_encode($response);
}
}
} else {
echo "Petición no válida";
}
} else {
echo "Acceso denegado";
}
?>
Para comprobar la acción que vamos a realizar se enviará desde la app Android un parametro tag. Los valores serán login o register. En el login se buscará al usuario y si todo va bien se enviará un json con los datos del usuario. En caso contrario se envía un json con el motivo del error y un código de error.
El caso del registro es parecido, se registra al usuario y se crea un json con sus datos que devolveremos. En el caso de no enviar el tag o que no corresponda con algo esperado devolvemos texto plano ya que estas peticiones vendrán desde fuera de nuestra app Android y no conviene dar pistas sobre lo que se necesita para loguear un usuario.
Por último queda crear la tabla de base de datos donde almacenaremos a nuestros usuarios.
CREATE TABLE IF NOT EXISTS `users` (
`uid` int(11) NOT NULL AUTO_INCREMENT,
`unique_id` varchar(23) NOT NULL,
`name` varchar(50) NOT NULL,
`email` varchar(100) NOT NULL,
`encrypted_password` varchar(80) NOT NULL,
`salt` varchar(10) NOT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`uid`),
UNIQUE KEY `unique_id` (`unique_id`),
UNIQUE KEY `email` (`email`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Es una tabla muy simple donde guardaremos el nombre, email y contraseña encriptada del usuario, también datos como la fecha de creación, última actualización.
Por último, os recuerdo que este ejercicio es muy simple y que debéis extremar las medidas de seguridad a la hora de almacenar datos de usuarios. Nunca guardar su password sin encriptar, el servidor es recomendable que utilice una conexión https. Verificar las consultas en busca de vulnerabilidades como SQL inyection.
Hasta aquí llega la parte de servidor, como veis esta parte no es muy larga ni difícil, ya que se trata de unas pocas operaciones que nos ayudarán en la tarea de autenticar a los usuarios contra la base de datos de vuestro servidor.