Sobre la normativa de uso de cookies en sitios web

A raíz de la aparición de artículos de abogados haciendo referencia a las primeras sanciones por el uso “incorrecto de cookies”, concretamente este, he decidido publicar por aquí mi opinión sobre el tema.

Contexto

Hace relativamente poco tiempo, se aprobó una reforma por la cual se obligaba a los sitios web que instalasen cookies a notificar al usuario y pedir confirmación de que el mismo deseaba instalarlas en su navegador antes de que el sitio web lo hiciese.

La AEPD publicó una guía para explicar en detalle cómo y por qué se debe avisar al usuario de que el sitio web almacena información en su navegador.

Problema

Podemos decir que todos los sitios y aplicaciones web en Internet a los cuales se accede desde un navegador necesitan usar cookies. Hay excepciones, pero no pertenecen a lo que podemos calificar como sitio web o aplicación web normal.

Algunas cookies permiten que el usuario pueda iniciar sesión, otras recordarle aunque cierre el navegador para que no tenga que volver a indicar su usuario y contraseña, otras ayudan a mejorar la usabilidad y posicionamiento de la página, otras ayudan a mejorar la precisión a la hora de mostrar anuncios al usuario y otras tienen fines que podemos calificar de menos éticos.

Hasta ahora, el uso de las cookies se especificaba en los términos y condiciones del sitio web pero tras la reforma ya esto deja de ser suficiente y tendremos que avisar al usuario de que vamos a instalar cookies – antes de hacerlo – que hacen funcionar cosas tan normales como Google Analytics, videos de Youtube o el ya típico login  de Facebook.

El problema reside en que un aviso similar al que se pide puede echar atrás a una persona que no está entrenada o no entienda muy bien “los riesgos” que conlleva dejar al sitio web instalar las cookies.

Estamos viendo noticias de cómo Gobiernos espían a sus usuarios, cómo redes sociales hacen data mining con los datos de sus usuarios para venderlos a marcas o agencias de marketing, cómo se dan casos de estafa en sitios web y, aunque estas cosas tengan poco o nada que ver con el tema que estamos tratando, los usuarios ya tienen una desconfianza adquirida por ese contexto.

Esa desconfianza también es adquirida gracias a sitios web que permiten ver contenido online como series o películas, en las que al usuario se le bombardea con decenas de avisos en los que debe “aceptar o cancelar” y, dependiendo si se equivoca o no, puede acabar en un anuncio de contenido bien distinto a lo que buscaba.

Personalmente creo que el contexto no es favorable para añadir avisos o notificaciones que alerten al usuario de que vamos a hacer algo que llevamos haciendo desde que existe Internet y no tiene por qué suponer un riesgo a esa persona o su navegador.

Por otro lado, el rechazar el uso de cookies puede generar una mala experiencia de usuario que perjudique directamente al negocio y ventas.

Ni decir tiene que si un sitio instala cookies para mostrar publicidad al usuario y es su modelo de negocio principal, el que el usuario rechace las mismas puede suponer un problema muy serio para dicha empresa.

Una solución mejor

Aunque creo que es labor del usuario conocer de otra forma que existe un contrato con ese servicio y que en ese contrato se especifique cómo gestionar las cookies referentes a ese sitio web, pienso que una solución mejor sería que fuesen los navegadores los que se encargasen de la tarea de avisar al usuario por defecto, sin tener que configurar nada en los mismos.

De esta forma los usuarios aprenderían a reconocer y diferenciar este tipo de avisos, de otros como banners o advertencias que aparezcan en el propio sitio web.

Actualmente recae en el sitio web el poner la advertencia, y eso puede influir a que cada uno use un diseño y textos distintos, en idiomas distintos. Algo que algunos sitios web podrían usar en contra del usuario, mostrando avisos similares para confundirle y terminar llevándole a una página publicitaria o algo más ofensivo.

Por favor, pásame la factura de este café

Hace unos meses, quedé con un cliente para tomar un café. No era una reunión de trabajo, simplemente era un café, para hablar y compartir un respiro en nuestras agendas.

Me encanta compartir puntos de vista y experiencias con otras personas que luchan por su negocio cada día. Lo considero algo muy importante, no sólo para cuidar tu red de contactos, sino para aprender de gente que hace cosas de verdad en lugar de sumarse a la fiesta publicitaria de emprender.

Lo que me dejó descolocado fue algo que ocurrió cuando nos íbamos a despedir: mi cliente me pidió que le hiciese factura por ese tiempo que habíamos compartido. “Asier, he aprendido mucho de este café y me has descubierto nuevos puntos de vista de mi negocio que ni me había planteado, por favor pásame factura por esto.”.

Puede que otras personas de perfil consultor más senior hubiesen visto esto como algo normal, pero a mí me chocó rotundamente.

Después de todas las actitudes y aptitudes que te encuentras al montar un negocio en España por parte de personas que buscan liderar un proyecto, sobre todo en Internet, este tipo de anécdotas te dan seguridad en seguir trabajando y mimando la pasión que nos hace caminar a la oficina con ganas de hacer cosas.

Este hecho, que me cogió por sorpresa, me ha confirmado en la importancia de seleccionar muy bien con quien trabajamos, tanto clientes como proveedores, incluso en medio de la crisis que estamos experimentando.

Cómo configurar el “remember me” en Silex

Hoy he implementado la funcionalidad de remember me en una aplicación Silex haciendo uso de los proveedores SecurityServiceProvider junto al RememberMeServiceProvider.

Al registrar el RememberMeServiceProvider me daba la siguiente excepción:

InvalidArgumentException: Identifier “security.remember_me.service.{key del firewall}” is not defined.

El problema residía en que registraba el RememberMeServiceProvider antes del SecurityServiceProvider, y eso era lo que lanzaba esa excepción.

Por lo tanto, para que funcione sin problemas deberíamos tener una configuración como la siguiente, respetando como he dicho el orden a la hora de registrar los proveedores de servicios:


$app->register(new Silex\Provider\SessionServiceProvider());


$app->register(new Silex\Provider\SecurityServiceProvider(), array(
    'security.firewalls'    => array(
        'site'  => array(
               
               'remember_me'   => array(),
               'pattern'       => '^/',
               'anonymous'     => true,
               'form'          => array(
                          'login_path' => 'login',
                          'check_path' => 'login_check'
                ),
                'users' => $app->share(function () use ($app) {
                    return new \Lib\UserProvider($app);
                }),
                'logout' => array('logout_path' => 'logout'),
         ),
    ),
    'security.access_rules' => array(
         array('^/login', 'IS_AUTHENTICATED_ANONYMOUSLY')
    )
));

$app->register(new \Silex\Provider\RememberMeServiceProvider());

No contar tus metas

Derek Sivers es una de las personas que más me inspiran en el mundo, es una pena que no haya tenido la oportunidad de desvirtualizarlo todavía.

Esta semana descubrí la siguiente charla en TED y me dio mucho en qué pensar. En ella se comenta cómo nuestro cerebro confunde lo que socialmente anunciamos que vamos a hacer o estamos haciendo, asumiéndolo como algo que realmente ya hemos hecho.

Una de las cosas de las que me suelo arrepentir es que suelo comentar demasiado pronto mis ideas cuando las veo perfectamente factibles o empiezo a ejecutarlas. No siempre termino la ejecución, o cuando lo hago, puede ser años después de cuando las he empezado.

En mi caso puede que no termine de ejecutar algo por los siguientes motivos: me he dado cuenta de que no era tan buena idea como pensaba, he priorizado otras cosas más importantes sobre la misma, la he aparcado para ejecutarla más adelante o estoy en proceso de solventar un problema clave en la misma.

La ejecución de una idea no se percibe bien cuando no se ejecuta a corto plazo, aún cuando sea imposible ejecutarla de forma adecuada en un periodo corto de tiempo. Psicológicamente y a nivel de negocio, también es un problema no ejecutar rápido, de ahí la importancia de planear buenos MVP.

Hasta ahora, sólo le había dado importancia al guardar en secreto los proyectos de mis clientes y no me preocupaba exponer abiertamente los míos a pesar de que alguien pudiese criticarme por no terminarlos. Sin embargo, la siguiente charla me ha roto un poco los esquemas y he estado pensando en que puede ser buena idea aceptar el consejo.

Desarrollar un servicio VS vender un servicio

Una de las cosas más interesantes de ofrecer servicio de desarrollo a clientes es lo que puedes aprender de perfiles no relacionados con la tecnología. Muchas veces descubres puntos de vista que te muestran realidades que van en contra de lo que has asumido o que no has visto por estar demasiado centrado en aspectos de desarrollo o ejecución.

Hace cinco años se dieron las condiciones para que los desarrolladores de aplicaciones web se pudiesen lanzar a crear servicios SaaS como la solución perfecta a la problemática de escalar sus negocios.

Desarrollar un producto y mantenerlo a cambio de pequeñas suscripciones suena como la salvación y camino a seguir, en lugar de tener que empezar de cero cada vez intentando ser cada año más competitivos en precio y tiempo, sobre todo ante clientes que no tienen ninguna experiencia en el sector y desconocen el coste de estos recursos a la hora de desarrollar proyectos de este tipo.

Durante estos cinco años hemos visto aparecer todo tipo de soluciones de este software como servicio, la mayoría muy factibles de desarrollar por un equipo de pocos desarrolladores con experiencia. Sin embargo, a pesar de esa aparente facilidad de ejecución, unas triunfan y otras se quedan en el camino, lo cual nos hace pensar con razón de que las cosas no pueden ser tan fáciles y que nos falta información.

A nada que nos adentramos en el apasionante mundo de los emprendedores tecnológicos, podemos encontrar historias de personas que salen de la nada y en menos de un año se vuelven millonarios y que gente muy simpática acude a ellos para inyectarles millones de dólares en sus negocios, casi suplicándoles que los acepten.

La realidad es fácil de comprobar cuando realmente decides ejecutar un proyecto en Internet que quiere ser rentable. En mi experiencia algunas cosas que he aprendido en los primeros años son las siguientes:

  1. Afortunadamente las cosas no son tan fáciles en general. Siempre hay variables que hay que resolver que van apareciendo segun te vas enfrentando al mercado real.
  2. Los desarrolladores que salen de la nada y reciben inversiones, ni salen de la nada, ni obviamente huelen ese dinero. La mayoría incluso se ven obligados a esclavizarse por un proyecto que nunca será lo que ellos pensaron al principio.
  3. En España, las subvenciones sólo las reciben personas bien situadas o que se dedican casi profesionalmente/socialmente a conseguirlas o que invierten dinero en conseguirlas.
  4. Puedes desarrollar un servicio, pero debe haber un negocio detrás.
  5. Hay servicios y empresas que no son conocidos por revistas o círculos de emprendedores que funcionan muy bien, venden y tienen mucha experiencia en el mercado.

El punto 4 es algo en lo que veo fallar frecuentemente, y no sólo es un fallo habitual en programadores.

En parte este punto es el que hace que asumamos cosas erróneas o nos pongamos una venda en los ojos, a menudo culpando al mercado, el momento o la crisis convirtiéndolos en motivos de nuestros fracasos.

Algunas cosas que suelo ver en perfiles de todo tipos, programadores o no, son las siguientes.

Esperar a tener el producto terminado para venderlo.

Tengo una mala noticia por si te ha chocado esta frase, el producto nunca se termina. Un síntoma de que no vas a se capaz vender el producto es si no eres capaz de venderlo sin tenerlo acabado.

Los desarrolladores cuando desarrollamos un servicio tendemos a enfocarnos en el desarrollo, esto es lo normal si nuestro rol es el desarrollo, pero si nuestro rol también es el de venta, hay que vender desde el día cero y tener un enfoque adecuado.

Vender es lo más importante y es la opción más inmediata para recibir feedback válido. El feedback de usuarios gratuitos o a los que no les supone un coste tu servicio no es tan preciso. Si tu producto no interesa, lo vas a ver de inmediato cuando intentes convencer a alguien de que invierta su dinero en él.

La sensación de vender humo es algo que los desarrolladores detestamos, pero es necesario dejarla atrás. Si eres desarrollador y estás fabricando el producto, no estás vendiendo humo, estás vendiendo el producto que estás desarrollando, punto.

De mis clientes y de la experiencia de los servicios en los que he participado, esta es una de las ideas que más me ha costado aprender y más valor creo que me ha aportado para tener un punto de vista adecuado.

El servicio o producto no se vende por sí solo.

Comprar y dominio, apuntar el DNS a tu servidor, lanzar un par de frases en Twitter o Facebook al día y esperar a que entren clientes, ¿fácil verdad? Demasiado para ser cierto.

El problema se complica si el producto encima no está terminado aún.

Hay que añadir algo más a los esfuerzos de venta, ¿el qué? tú debes saberlo y debes saberlo ya, esta es la parte complicada de hacer que un negocio funcione, bienvenido a la realidad.

Saber vender es lo que hace que unos caigan y otros funcionen, “cómo hacerlo bien” es la asignatura que estamos aprendiendo en el día a día todos y cada uno de los que nos dedicamos en serio a esto.

No todo es el software.

Pensar en servicios que sean complementarios a tu software no está de más en un sector en el que como ya he dicho, todos tenemos el mismo problema que tú: un software que vender.

Quizá una posible vía es explotar servicios que complementen a tu servicio principal. Puede que le reste escalabilidad dependiendo del tipo de servicio, pero de nada te sirve un modelo escalable que tiene cero clientes.

No todo es suscripción.

Ojalá lo fuese, pero en algunos servicios no hay valor suficiente para que tus usuarios acepten este tipo de modelo.

Y no se trata de precio, sino de percepción de pagar por algo que no se usa. En algunos casos se puede encontrar un modelo que suponga los mismos ingresos con los mismos usuarios, sin necesidad de suscripción.

Comunicación.

La comunicación no es actualizar Twitter o Facebook, ni poner un logotipo en un evento. Hoy en día eso ya no vale, la comunicación requiere identidad, la identidad requiere personalidad y la personalidad requiere pasión.

Y la pasión no entiende de medios, sino de sentidos.

Aprender a expresar en palabras que abran los sentidos de tus clientes es el reto. Es mi lucha personal, un reto al que me enfrento cada día y por el cual intento aprender con envidia sana de aquellos que logran transmitir con su voz algo que se compra de forma natural. Es algo casi poético y una cualidad que admiro en las personas.

Si no comunicas no existes. En algunos momentos o por tipo de servicios no existir está bien, en serio, pero cuando hay que vender un producto a consumidor final, es importante comunicar para que se vea que estás vivo y en proceso de mejora continua.

La tecnología.

En el 2008 la gente “normal” empezó a comprar móviles en los que se instalaban aplicaciones, sin tener conocimientos de programación ni dedicarse a este sector. No conocen las tecnologías detrás de iOS o Android, ni les interesa saberlo, simplemente pagan y usan el producto.

Programar tu producto en Python y decir que “Python es sexy” no va a hacer que vendas más. La gente que trabaja en WhatsApp a veces publica benchmarks sobre el rendimiento de su backend en erlang, pero eso no les ayuda a vender más, lo han hecho gracias a otras cosas que hemos visto este año, una lección que todo desarrollador debe aprender.

Las tonterías se acaban cuando la gente tiene que pagar dinero por lo que haces.

Como conclusión, sin el desarrollo los servicios no existen, sin ventas los negocios tampoco.

Límites y pensamiento lateral

Hay muchas personas que creen erróneamente que la creatividad es algo con lo que nacemos y que no se puede adquirir o mejorar mediante estudio o entrenamiento.

Lo cierto es que cuando pensamos, nuestro cerebro lo hace de forma lógica, buscando patrones con modelos que ya conoce y de no hacerlo, los recuerda y va afianzando en nuestra memoria a medida que nos volvemos a encontrar con problemas similares.

Aunque este funcionamiento hace que seamos increíblemente resolutivos, a veces la solución que buscamos requiere salirse de toda norma, de toda lógica.

La creatividad nos permite encontrar soluciones nuevas o distintas a las que encontramos lógicas y evidentes, que no tienen por qué ser mejores.

Una de las formas de conseguir escapar del pensamiento lógico para encontrar soluciones distintas a lo típico es el pensamiento lateral.

Escuché hablar sobre el pensamiento lateral hace unos ocho años y desde entonces no he dejado de leer libros del creador del término, Edward de Bono, autor también de la técnica de los seis sombreros para pensar.

En uno de sus libros, nos demuestra que nuestro pensamiento lógico nos lleva a asumir ciertos límites que no existen a la hora de pensar y resolver problemas.

Un ejemplo se ve claramente al intentar unir todos los puntos en el siguiente dibujo realizando sólo cuatro trazas sin levantar el lápiz del papel.

dots1

Si lo intentamos como haría una persona normal, llegaremos a la rápida conclusión de que es imposible hacerlo, pero no lo es.

Si vemos la solución en este enlace, rápidamente nos daremos cuenta de que hemos asumido que había un límite que no era real, el borde que forman los círculos exteriores.

Este es sólo un ejemplo en el que se ve de forma simplificada cómo nuestro cerebro nos hace pensar que no podemos resolver ciertos problemas, cuando en realidad la solución es viable.

Ejercitar el pensamiento lateral no es algo sumamente complicado, hay diferentes técnicas en las que nos planteamos ejercicios en los que debemos dar soluciones a cosas que aparentemente no la tienen, sin asumir límites o dejando de lado a priori las razones por las que no se pueden conseguir.

En otro ejemplo se nos retaba a situar cuatro árboles en tal posición que la distancia de cada uno respecto a los otros fuese la misma. En este caso, se debía jugar con la altura del terreno para conseguirlo, pero no es algo en lo que pensemos de forma directa.

Una vez que la solución se muestra ante nosotros, nuestro pensamiento lógico la comprende y en algunos casos la clasificamos de evidente o nos provoca el quejarnos de la existencia de una trampa en el enunciado del problema, cuando hemos sido nosotros mismos los que hemos puesto el límite en primer lugar.

Silex con Doctrine DBAL y ORM

En este artículo explicaré cómo utilizar Doctrine y sus entidades en el microframework Silex.

Aunque no es obligatorio, os recomiendo que utilicéis el “esqueleto” para Silex que ha creado Fabien Potencier para estructurar los archivos, o al menos le echéis un ojo para tenerla como ejemplo.

Para tener una integración completa de Doctrine en Silex, necesitaréis los siguientes providers y librerías:

  • DoctrineServiceProvider
    Es un proveedor de servicios oficial, que nos permitirá utilizar DBAL, la capa que nos da Doctrine para trabajar de forma sencilla con PDO.
  • Doctrine ORM ServiceProvider de Dragonfly Development
    Este proveedor nos permitirá trabajar con Doctrine ORM y sus entidades.
  • DoctrineBridge
    Con DoctrineBridge tendremos las librerías necesarias para poder loguear nuestras consultas sin tener que hacer un desarrollo propio para ello.

Los pasos para tener todo funcionando son los siguientes:

Configurar las dependencias en el composer.json

Debemos añadir los siguientes requires para descargar las dependencias anteriores


"doctrine/dbal": "2.*",
"symfony/doctrine-bridge": "2.*",
"dflydev/doctrine-orm-service-provider": "1.0.*@dev"

Una vez añadidas las anteriores líneas a nuestros requires, actualizamos con composer:

php composer.phar update

Registrar los ServiceProvider

Si utilizamos el skeleton de Fabien, los incluiremos en el archivo app.php, en caso contrario, los añadiremos en el lugar donde estemos registrando el resto de los ServiceProviders.


$app->register(new Silex\Provider\DoctrineServiceProvider(), array(
    'db.options'    => array(
    'driver'        => 'pdo_mysql',
    'host'          => 'localhost',
    'dbname'        => 'name',
    'user'          => 'root',
    'password'      => '',
    'charset'       => 'utf8',
    'driverOptions' => array(1002 => 'SET NAMES utf8',),
  ),
));

$app->register(new Dflydev\Silex\Provider\DoctrineOrm\DoctrineOrmServiceProvider, array(
    "orm.em.options" => array(
         "mappings" => array(
            array(
               "type"      => "yml",
               "namespace" => "Entity",
               "path"      => realpath(__DIR__."/../config/doctrine"),
              ),
            ),
         ),
));

Como vemos, primero registramos el Provider oficial, en el que indicamos los datos de conexión. Si dispusiésemos de varios servidores de bases de datos, para dividir las escrituras y las lecturas por ejemplo, este sería el lugar para hacerlo.

A continuación, registramos el proveedor de dflydev para disponer del ORM. Es importante fijarse en los parámetros

  • type: Define qué tipo de mapeo queremos para las entidades de doctrine. Las posibilidades son annotations, yml o xml.
  • namespace: Indica el namespace para las clases del ORM.
  • path: Indica en qué carpeta tenemos la configuración de las entidades.

Yo he optado por utilizar un mapeo basado en Yaml y guardo los mapeos en la carpeta /config/doctrine. Las clases de las entidades estarán bajo el namespace Entity.

Añadir los comandos de Doctrine

Para disponer de los comandos que nos permitirán generar las entidades, vamos al archive console.php entro del directorio src si utilizamos el skeleton, en caso contrario vamos al archivo donde tengamos la configuración de la consola y añadimos lo siguiente:


$console->setHelperSet(new Symfony\Component\Console\Helper\HelperSet(array(
    'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($app["db"]),
    'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($app["orm.em"])
)));

$console->addCommands(array(

  new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand,
  new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand,
  new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand,
  new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand,
  new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand,
  new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand,
  new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand,
  new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand,
  new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand,
  new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand,
  new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand,
  new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand,
  new \Doctrine\ORM\Tools\Console\Command\InfoCommand,
  new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand,
  new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand,
  new \Doctrine\DBAL\Tools\Console\Command\ImportCommand,
  new \Doctrine\DBAL\Tools\Console\Command\ReservedWordsCommand,
  new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand

));

Esto registrará los comandos y helpers que nos da doctrine para gestionar las entidades y el esquema de base de datos.

Uso en la aplicación

Tras estos pasos sólo nos queda usarlo. Para ello creamos el mapa de entidad Entity.User.dcm.yml en el directorio que hayamos indicado en la configuración del proveedor:

#config/doctrine/Entity.User.dcm.yml
Entity\User:
    type: entity
    table: user
    fields:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
        email:
            type: string
            length: 255
        password:
            type: string
            length: 512
    lifecycleCallbacks: {  }

Ahora, mediante la línea de comandos ejecutamos lo siguiente.

php console orm:generate-entities src/ --generate-annotations=1

Esto nos creará la carpeta Entity/ en el directorio src/ con las clases de las entidades, en este caso la clase Entity\User.

Para crear la base de datos, utilizaríamos el comando

php console orm:schema-tool:create

Esto nos creará la base de datos en el servidor. Ahora ya sólo nos queda el realizar operaciones con nuestros usuarios.

$app->get("/test-users", function(Application $app){

  $user = new \Entity\User();
  $user->setEmail("example@simettric.com");
  $user->setPassword("lalala");

  $entity_manager = $app["orm.em"];

  $entity_manager->persist($user);
  $entity_manager->flush();

  $users = $entity_manager->getRepository("Entity\User")
                          ->findAll();

  return $app['twig']->render('users.html.twig',
                              array("users"=>$users));

});

Seguridad.

Si utilizamos el SecurityProvider, seguro que unos interesa realizar la autenticación con nuestros usuarios en la base de datos utilizando Doctrine.

Para ello lo primero que debemos hacer es crearnos un UserProvider.


namespace Lib\Provider;

use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\User;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;

class UserProvider implements UserProviderInterface
{
    private $app;

    public function __construct(\Silex\Application $app)
    {
        $this->app = $app;
    }

    public function loadUserByUsername($username){


        $em = $this->app["orm.em"];
        if($em instanceof \Doctrine\ORM\EntityManager){
            if(!$user = $em->getRepository("Entity\User")->findOneBy(array("username"=>$username))){
                throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));
            }
        }

        return $user;

    }

    public function refreshUser(UserInterface $user)
    {
        if (!$user instanceof \Entity\User) {
            throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
        }

        return $this->loadUserByUsername($user->getUsername());
    }


    public function supportsClass($class)
    {
        return $class === '\Entity\User';
    }



}

Y en nuestra configuración de seguridad, añadir lo siguiente

$app->register(new Silex\Provider\SecurityServiceProvider(), array(
    'security.firewalls'    => array(
        'dev' => array('pattern' => '^/(_(profiler|wdt)|css|images|js)/', 
                       'security' => false),
        'site' => array(
            'pattern'     => '^/',
            'form'        => array('login_path' => 'login',
                                   'check_path' => 'login_check'),
            'users'       => $app->share(function () use ($app) {
                return new \Lib\Provider\UserProvider($app);
            }),
            'logout' => array('logout_path' => 'logout'),
        ),
    ),
    'security.encoders'  => array('Entity\User'=> array(
                                     'algorithm'        => 'sha1', 
                                     'iterations'       => 4,         
                                     'encode_as_base64' => false
))));

Con esto ya tenemos nuestro sistema de seguridad autenticando con nuestros usuarios de la base de datos, utilizando Doctrine.

Lo que le diría a mi yo del pasado

La primera vez que barajé la idea de montar un negocio, de forma lejana y totalmente ilusa por supuesto, fue en el 2004.

Tenía 21 años, acaba de terminar el grado superior de administración de sistemas informáticos en el colegio Gaztelueta, hecho las prácticas en el colegio Munabe, y estaba estudiando el MCSE (Microsoft Certified Systems Engineer) de Microsoft, con la especialidad de mensajería con servidores Exchange 2003, mientras hacía trabajos por mi cuenta de desarrollo web en php.

Por aquella época intentaba buscar trabajo de desarrollador web pero era imposible, los entrevistadores de las consultoras informáticas a las que me presentaba me decían que eso no tenía futuro, que era una moda.

En el 2006 inicié un negocio con otras cuatro personas que no fue a ninguna parte y, en el 2008 di el paso de trabajar como autónomo, el resto ya lo sabéis (más o menos ;).

Estos son una serie de cosas que le escribo a mi yo del pasado, el del 2008, que cansado de trabajar como consultor de tecnologías IT Microsoft por el día (trabajo que odiaba pero que no se le daba mal) y desarrollador de proyectos web personales de noche, está a punto de embarcarse en una aventura de no retorno.

1. La tecnología no es tu arma principal.

Este es un punto amargo. Desarrollar es duro (realmente duro), gestionar servidores puede ser el peor de los infiernos en determinados momentos (en serio, un verdadero infierno) y la gente que no es técnica ni lo sabe ni se preocupa por saberlo.

Para alguien acostumbrado a hacer sacrificios e invertir tiempo en aprender y mejorar sus conocimientos tecnológicos, es duro aceptar que la tecnología no es lo más importante, sobre todo cuando el resto del mundo no lo suele valorar, pero hay que hacerlo.

Para crear cualquier negocio hay que aprender a quitarse el parche de la tecnología y tener perspectiva para poder avanzar y ofrecer valor.

2. No debes hacerlo tú todo.

Lo primero que debes saber cuando quieres montar un negocio es si quieres que sea un autoempleo o una empresa. Ninguna de las dos opciones es mejor o peor que la otra.

Estoy harto de conocer emprendedores que creen que un autoempleo o una empresa que no es invertible a ojos del gurú inversor de turno al que no conocen, es una especie de vergüenza. En el fondo no me extraña con toda la basura que se publica y consume sobre emprendedores e inversores.

Sin embargo, lo importante sí que es conocer una obviedad si decides tomar el camino del autoempleo: el día tiene 24 horas, de las cuales sólo 6 pueden ser realmente útiles en un día de suerte, el resto es quemarse y en algunos casos, hacer el tonto.

Delegar, que no implica necesariamente contratar, es un ejercicio imperativo si se quiere sacar trabajo adelante.

Es fácil decirlo, pero hay que encontrar proveedores de confianza, con los que puedas tener buena comunicación y la seguridad de que van a estar cubriéndote la espalda. Es un reto, un reto de los más difíciles, pero lograrlo te hace conseguir las cosas. Cuida a tus proveedores, mejor incluso que a tus clientes.

Ten en cuenta siempre que lo perfecto es lo enemigo de lo bueno, deja que otros te ayuden a hacer cosas que igual no están perfectas, pero estarán hechas.

Si decides que no quieres un autoempleo, como es mi caso en este momento, delegar no es opcional a ningún nivel. Aprende y acostúmbrate a no ser tú el que haga las cosas cuanto antes.

Sobre contratar, no te precipites. Si crees que debes hacerlo, asegúrate una entrada de dinero constante que no sea un pico puntual y sobre todo que la persona que vayas a contratar tenga iniciativa para tomar decisiones, preocupación por aprender y sea capaz de trabajar sin que tú estés encima. Nunca, repito NUNCA, busques un crédito para contratar, es preferible que tú no cobres antes de hacer eso.

Por último, si finalmente vas a contratar, prepárate para el día que tengas que despedir, sea familiar, amigo, pareja o una buena persona a la que harías la mayor putada de su vida.

3. Conoce tus gastos, tu liquidez real y gestiona tu dinero.

Si el asesor, porque DEBES tener un asesor, te da una sorpresa por la cantidad de dinero  que no has previsto tener que pagar de IVA y lo que has retenido a tus proveedores es que lo estás haciendo mal.

Lo que tienes en la cuenta no es tu dinero, es un número que a veces no coincide con lo que realmente es tuyo.

Debes saber qué dinero tienes en todo momento, conocer al detalle todos tus gastos siempre (en especial los que son recurrentes, aunque sean pequeños pagos de 10€ al mes) y el que debes pagar en el próximo trimestre.

4. Networking. (en serio)

No, no voy a decirte que vayas a todos los eventos para emprendedores, eso no es networking de verdad, aunque lo acabarás viendo.

Es importante ir a eventos, ir a iniciativas que tengan que ver con lo que haces o vendes y si no existe, organízalos tú.

Muchos emprendedores pierden la cabeza y se convierten en vendedores de emprendimiento. No te va a interesar vender que eres emprendedor, te interesa vender lo que tú haces y al resto también le interesa que lo hagas porque así se crea mercado, no dando charlas sobre cómo emprender.

Si quieres conocer a alguien, aprende a presentarte como es debido e invítale a un café. No le vendas nada, ni se te ocurra. Si lo que haces realmente tiene valor, no necesitas venderlo a toda costa, simplemente debes saber transmitir que lo tiene. Si consigues transmitir eso, te aseguro que va a querer comprarlo y si a él no le interesa, puede que se acuerde de otros que él conoce, y que están fuera de tu radar, a los que puede interesarles.

Conociendo a gente, aunque no sean de tu sector (y a veces es mejor que no lo sean), vas a descubrir personas increíbles y eso te va a hacer ver la vida de otra forma.

5. No es personal.

Tu negocio no eres tú. Si todo lo que eres, es tu negocio, si crees que tu valor es ese, estás condenado a que ni tu vida ni tu negocio te llenen jamás.

La falta de experiencia va a hacer que pierdas oportunidades y a personas que quieres más que a ti mismo a nivel personal. Y aprenderás.

Las cosas importantes no van a esperar a que montes tu negocio y que todo vaya genial, o las haces en el día a día o no las haces.

Simplemente ten en cuenta que tu negocio será mejor para ti si tú eres feliz. Unos trucos para ser feliz

  • Selecciona a tus clientes.
  • Duerme y descansa.
  • No respondas a un email o lo escribas inmediatamente si te ha sentado algo mal. Espera todo el tiempo que necesites, aunque sea una semana.
  • Si tienes la sensación de que un cliente, un proveedor o sobre todo un socio está en contra tuya, habla con él por teléfono o escribe todo lo que piensas de forma clara. NUNCA te guardes nada porque pienses que no merece la pena decirlo y va a dar igual. Todo claro y a la cara.
  • Si vas a unirte en un proyecto con socios, ese proyecto no es tuyo, es de todos. Se tomarán decisiones que sabrás que son erróneas o con las que no estarás de acuerdo y debes aprender a aceptarlas y a hacer frente a sus consecuencias.
  • Haz deporte, en serio, haz deporte.
  • Busca una vía de escape: leer, amigos, sexo, aprender idiomas, lucha libre..

6. Invierte bien tu esfuerzo y dinero.

Pronto aprenderás que el verdadero negocio, y en el que tendrás más posibilidades de ser feliz, es crear un producto que la gente compre en lugar de hacer un macrodesarrollo a medida para cada cliente. Pero… ¿recuerdas el punto 1?

Antes de pensar en programar averigua cómo vas a venderlo, a qué precio y a cuántas personas.  Si después de hacer cuentas y evaluar tus posibilidades piensas que tendrás éxito, intenta asegurarte clientes antes de hacerlo. No es fácil, pero esto es en lo que consiste un negocio.

Por muy sencillo que sea un proyecto, va a necesitar mucha dedicación, dinero y al final puede que no funcione a pesar de que vieses su éxito muy claro al principio.

Las razones por las que un proyecto puede funcionar pueden ser muchas, incluso hay veces que no funcionan en un momento del mercado específico, en un momento de tu vida específico o con ciertos socios.

Hay que saber también retirarse del juego a tiempo, aunque se haya puesto dinero o esfuerzo, ningún precipicio tiene pinta de ser agradable de recorrer de cabeza y sin paracaídas.

Vas a necesitar una disciplina basada en tareas que debes ejecutar. Aprende a priorizar y enfocarte a ejecutar tareas por orden de valor. No vas a poder hacerlo todo, pero que eso no te impida avanzar.

Sé selectivo con los eventos a los cuales acudes, con los proyectos en los cuales te metes, con los servicios que vas a ofrecer y con los clientes con los que vas a trabajar.

7. Nadie tiene tus ojos. (ni lo que hay detrás de ellos)

Te van a criticar, a decir lo equivocado que estás (incluso cuando lo estés), vas a dudar de si lo que has hecho está bien o mal, vas a sentirte sólo, muy sólo.

Sólo puedo decirte que si tomas una decisión, que sea tuya y porque estés 100% seguro, tú debes saber por qué lo haces y cual es el motivo. Como la típica frase: si tienes dudas, es que no hay duda.

Debes mejorar tu comunicación. Ofrecer algo conlleva a explicarlo, a explicar por qué lo has planteado de una forma y no de otra, debes poder ser entendido de una forma clara y precisa, a pesar de estar bajo un estrés brutal.

Hay situaciones en las que es imposible, a día de hoy aún no sé expresar a veces por qué siento que debo tomar ciertas decisiones, aunque sepa con toda seguridad que son las correctas, pero hay que intentarlo.

8. Vas a fallar.

Algo que nadie te dirá, vas a fallar, y no será una sola vez de forma aislada. Cuanto antes aprendas que no siempre las cosas salen bien, menos posibilidad de cometer fallos y tener que sufrir las consecuencias de los mismos.

Conoce tus límites y sobre todo no seas torpe en lo referente al orgullo, repasa el punto 5 siempre que puedas, desconecta, haz lo que sea para estar mentalmente sereno.

Si crees que todo va a salir mal, frena y tómate las cosas con más calma. A veces para avanzar más hay que andar más despacio, cuidando cada paso.

9. No pospongas lo que te haga ilusión.

Como te he comentado, tu vida no va a esperarte hasta que tus proyectos funcionen como quieres.

Si algo te hace ilusión, aunque sea algo material, un antojo o tontería, satisfácelo. Tener ilusión es algo que nos hace poderosos.

Evidentemente doy por supuesto que tienes cabeza y no vas a gastarte todo en puffs o cosas así.

10. Pásalo bien. (topicazo, pero es verdad)

Tienes conocimientos, experiencia, hambre de aprender, vas a sacrificarte como si no hubiese mañana.. al menos no pierdas el norte y ten presente que al final esto es para ser feliz y tener calidad de vida.

Si al final el tomar este camino conlleva pasarlo mal, no tiene ningún sentido ni necesidad ni traerá nada bueno.

Rodéate de personas que sean buena gente, con las que se puedan hacer cosas que molen y disfruta de la experiencia. El resto lo superarás sin problema.

Symfony2 Security UsernamePasswordToken::serialize() must return a string or NULL

Today I got the following exception in a web application that uses Doctrine2 Entities and the Symfony Security Component with Silex framework (this can also appear in Symfony2 framework).

Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken::serialize() must return a string or NULL

ErrorException: Notice: serialize(): "id" returned as member variable from __sleep() but does not exist in /../vendor/symfony/security/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php line 149

The error appears when you have a Doctrine Entity implementing the UserInterface with a relation mapped in it.

The solution is as simple as implement the __sleep() magic method in that entity in this way.


public function __sleep(){
   return array('id', 'username', 'email');
}

This sets the id, email and username as the desired attributes to serialize ignoring the mappings and other properties in the Entity.