Autenticar usuarios con PHP

En esta parte del tutorial de Bookshelf para PHP, se muestra cómo crear un flujo de inicio de sesión para los usuarios y cómo usar la información del perfil para ofrecer a los usuarios funciones personalizadas.

Con Google Identity Platform, puedes acceder fácilmente a la información sobre los usuarios y al mismo tiempo garantizar que Google administre sus credenciales de inicio de sesión de forma segura. OAuth 2.0 facilita el flujo de inicio de sesión para todos los usuarios de la aplicación y proporciona a la aplicación acceso a información básica del perfil sobre usuarios autenticados.

Esta página forma parte de un tutorial de varias páginas. Para empezar desde lo básico y consultar las instrucciones de configuración, ve a la aplicación Bookshelf de PHP.

Crear una ID de cliente de aplicación web

Un ID de cliente de aplicación web permite que la aplicación autorice a los usuarios y acceda a las API de Google en nombre de los usuarios.

  1. Ve a la sección de credenciales en la consola de Google Cloud Platform.

  2. Haz clic en la pantalla de autorización de OAuth. Introduce PHP Bookshelf App en el nombre del producto. Completa los campos opcionales relevantes. Haz clic en Guardar.

  3. Haz clic en Crear credenciales > ID de cliente OAuth.

  4. En Tipo de aplicación, selecciona Aplicación web.

  5. En Nombre, introduce PHP Bookshelf Client.

  6. En URI de redirección autorizadas, introduce las siguientes URL, una a la vez. Sustituye [YOUR_PROJECT_ID] por el ID del proyecto:

    http://localhost:8000/login/callback
    http://[YOUR_PROJECT_ID].appspot.com/login/callback
    https://[YOUR_PROJECT_ID].appspot.com/login/callback
    http://[YOUR_PROJECT_ID].appspot-preview.com/login/callback
    https://[YOUR_PROJECT_ID].appspot-preview.com/login/callback

  7. Haz clic en Crear.

  8. Copia el ID de cliente y secreto de cliente y guárdalos para usarlos más tarde.

Establecer configuración

Copia el archivo settings.yml de la parte de Cloud Storage de este tutorial al directorio getting-started-php/4-auth. En el archivo copiado, sustituye YOUR_CLIENT_ID y YOUR_CLIENT_SECRET por el ID y secreto de cliente que creaste anteriormente.

Instalar dependencias

Introduce el siguiente comando en el directorio 4-auth.

composer install

Ejecutar la aplicación en la máquina local

  1. Inicia un servidor web local:

    php -S localhost:8000 -t web
    
  2. Introduce la siguiente dirección en el navegador web.

    http://localhost:8000

Ahora puedes navegar por las páginas web de la aplicación, iniciar sesión con tu cuenta de Google, agregar libros y ver los libros que agregaste mediante el enlace Mis libros en la barra de navegación superior.

Desplegar la aplicación en el entorno flexible de App Engine

  1. Despliega la aplicación de muestra:

    gcloud app deploy
    
  2. Introduce la siguiente dirección en el navegador web. Sustituye [YOUR_PROJECT_ID] por el ID del proyecto:

    https://[YOUR_PROJECT_ID].appspot.com
    

    Si actualizas la aplicación, puedes desplegar la versión actualizada al introducir el mismo comando que utilizaste para desplegar la aplicación por primera vez. El nuevo despliegue crea una nueva versión de la aplicación y la promociona a la versión predeterminada. Las versiones anteriores de la aplicación se mantienen, al igual que las instancias de VM asociadas. Ten en cuenta que todas estas versiones de aplicaciones e instancias de VM son recursos facturables.

    Si eliminas las versiones no predeterminadas de la aplicación, puedes reducir los costes.

    Para eliminar una versión de la aplicación, sigue las instrucciones a continuación:

    1. In the GCP Console, go to the Versions page for App Engine.

      Go to the Versions page

    2. Select the checkbox for the non-default app version you want to delete.
    3. Click Delete to delete the app version.

    Si quieres obtener información completa sobre cómo limpiar los recursos facturables, consulta la sección sobre limpiar los recursos en el último paso de este tutorial.

    Estructura de la aplicación

    En el siguiente diagrama, se muestran los componentes de la aplicación y cómo se conectan entre ellos.

    Estructura de muestra de autenticación

    Información sobre el código

    La sesión de PHP

    En este tutorial, se utiliza la administración de sesiones nativas de PHP y Memcache para no interrumpir la sesión de un usuario. El tiempo de ejecución de PHP se configura de manera predeterminada para usar Memcache para la configuración de la sesión. Esto nos permite usar SessionServiceProvider Silex para administrar los datos del usuario.

    Los usuarios iniciarán sesión con sus cuentas de Google y almacenaremos sus datos básicos de usuario en la sesión.

    $app->register(new SessionServiceProvider);
    // fall back on PHP's "session.save_handler" for session storage
    $app['session.storage.handler'] = null;
    $app['user'] = function ($app) {
        /** @var Symfony\Component\HttpFoundation\Session\Session $session */
        $session = $app['session'];
    
        return $session->has('user') ? $session->get('user') : null;
    };

    La biblioteca cliente de la API de Google para PHP

    El cliente PHP de la API de Google proporciona funciones de OAuth para que los usuarios se autentiquen con una cuenta de Google. Para hacer un buen uso de estas funciones, debemos crear la clase de servicio Google\Client y configurarla para nuestra aplicación.

    $app['google_client'] = function ($app) {
        /** @var Symfony\Component\Routing\Generator\UrlGenerator $urlGen */
        $urlGen = $app['url_generator'];
        $redirectUri = $urlGen->generate('login_callback', [], $urlGen::ABSOLUTE_URL);
        return new Google_Client([
            'client_id'     => $app['config']['google_client_id'],
            'client_secret' => $app['config']['google_client_secret'],
            'redirect_uri'  => $redirectUri,
        ]);
    };

    Cuando el usuario hace clic en Iniciar sesión, la acción GET '/login' utiliza nuestra clase de servicio de cliente PHP de la API de Google para generar la URL de autorización y redirigir la petición.

    $app->get('/login', function () use ($app) {
        /** @var Google_Client $client */
        $client = $app['google_client'];
    
        $scopes = [ \Google_Service_Oauth2::USERINFO_PROFILE ];
        $authUrl = $client->createAuthUrl($scopes);
    
        return $app->redirect($authUrl);
    })->bind('login');

    La URI redirect_uri que pasamos a la clase de servicio Google\Client se llama cuando el usuario hace clic en Permitir. Esta acción recibe un código de autorización que se usa para obtener un token de acceso. Los datos del token se almacenan en la sesión y se redirige al usuario a la página de inicio.

    $app->get('/login/callback', function () use ($app) {
        /** @var Request $request */
        $request = $app['request'];
    
        if (!$code = $request->query->get('code')) {
            return new Response('Code required', Response::HTTP_BAD_REQUEST);
        }
    
        /** @var Google_Client $client */
        $client = $app['google_client'];
        $authResponse = $client->fetchAccessTokenWithAuthCode($code);
    
        if ($client->getAccessToken()) {
            $userInfo = $client->verifyIdToken();
    
            /** @var Symfony\Component\HttpFoundation\Session\Session $session */
            $session = $app['session'];
            $session->set('user', [
                'id'      => $userInfo['sub'],
                'name'    => $userInfo['name'],
                'picture' => $userInfo['picture'],
            ]);
    
            return new Response('', Response::HTTP_FOUND, ['Location' => '/']);
        }
    
        // an error occured while trying to authorize - display it
        return new Response($authResponse['error_description'], 400);
    })->bind('login_callback');

    Cuando el usuario cierra sesión, la acción '/logout' borra la información del usuario de la sesión.

    $app->get('/logout', function () use ($app) {
        /** @var Symfony\Component\HttpFoundation\Session\Session $session */
        $session = $app['session'];
        $session->remove('user');
    
        return new Response('', Response::HTTP_FOUND, ['Location' => '/']);
    })->bind('logout');

    La información útil acerca de un usuario, como el nombre e imagen, se puede obtener una vez que el usuario se ha autenticado. Si han iniciado sesión, podemos mostrar esta información en nuestra plantilla base. Si no existe información del usuario, mostraremos un botón de inicio de sesión.

    {% if app.user %}
      {% if app.user.picture %}
        <img src="{{ app.user.picture }}" class="img-circle" width="24" alt="Photo" />
      {% endif %}
      <span>
        {{ app.user.name }} &nbsp;
        <a href="/logout">(logout)</a>
      </span>
    {% else %}
      <a href="/login">Login</a>
    {% endif %}
¿Te ha resultado útil esta página? Enviar comentarios: