Formato REST de inicio de sesión del usuario

13

¿Alguien tiene un inicio de sesión REST que funcione en Drupal 8?

Esto es lo que probé.

POST /user/login HTTP/1.1
Host: 8.d8.local
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: http://nikhilmohan.in
Cache-Control: no-cache

name=test&pass=password&form_id=user_login_form

Me devuelve HTML en lugar de JSON .

niksmac
fuente

Respuestas:

15

Mirando desde 8.2, Drupal admite puntos finales json para la autenticación de cookies. Ya no necesitas publicar el formulario 🎉

curl --header "Content-type: application/json" --request POST \
  --data '{"name":"admin", "pass":"admin"}' \
http://drupal.d8/user/login?_format=json

La salida se verá como

{"current_user":{"uid":"1","roles":["authenticated","administrator"],"name":"admin"},"csrf_token":"wBr9ldleaUhmP4CgVh7PiyyxgNn_ig8GgAan9-Ul3Lg","logout_token":"tEulBvihW1SUkrnbCERWmK2jr1JEN_mRAQIdNNhhIDc"}

Cambio de registro: https://www.drupal.org/node/2720655

Otros métodos de autenticación: https://www.drupal.org/docs/8/core/modules/rest/using-other-authentication-protocols

kalabro
fuente
No puedo hacer que esto funcione, obtengo 403 "Solo usuarios anónimos pueden acceder a esta ruta". por extraño que estoy usando REST, obviamente, no se ha identificado
Jim Smith
1
@jimsmith ¿Qué estás usando para probar la llamada? He tenido este problema antes de usar Postman porque estaba recibiendo mis cookies de Chrome y diciendo que había iniciado sesión. Puede probar esto al cerrar sesión en el navegador y enviar la solicitud nuevamente
Antero Duarte
11

Así es como puede iniciar sesión a través de JavaScript para Drupal 8 REST:

Drupal 8.2 y más allá

  • POST :http://example.com/user/login?_format=json
  • Tipo de contenido :application/json
  • Datos :{ "name": "admin", "pass": "myPassword" }
  • Respuesta :200 OK

Esto iniciará sesión correctamente a través de la autenticación de cookies y devolverá un resultado similar a este:

{
  "current_user": {
    "uid":"1",
    "roles":["authenticated"],
    "name":"admin"
  },
  "csrf_token":"abc123",
  "logout_token":"def456"
}

Creé un módulo contrib llamado jDrupal que hace que sea muy fácil iniciar sesión con JavaScript (entre otras cosas):

// Login and show the user their id.
jDrupal.userLogin('admin', 'myPassword').then(function() {
  alert(jDrupal.currentUser().id());
});

Antes de Drupal 8.2

  • POST :http://example.com/user/login
  • Tipo de contenido :application/x-www-form-urlencoded
  • Datos :name=admin&pass=myPassword&form_id=user_login_form
  • Respuesta :200 OK | 303 See Other

Enviarás los datos en la URL como una cadena de consulta. El resultado será HTML, por lo que no le devolverá nada útil, pero iniciará sesión correctamente a través de la autenticación de cookies.

tyler.frankenstein
fuente
¿Entonces devolver HTML es inevitable?
niksmac
En este punto AFAIK, sí, HTML es inevitable. Me imagino que esto mejorará con el tiempo, porque, por ejemplo, todavía no hay una manera de registrar un usuario a través de REST, pero se ha producido un problema.
tyler.frankenstein
no me ha funcionado, ¿es necesario usar también la autenticación básica?
Yusef
Para su información, JSON se devuelve a partir de Drupal 8.2, por lo que no se devuelve más HTML.
tyler.frankenstein
8
  1. Una solicitud HTTP no es RESTful basada en Content-Type.
  2. " Iniciar sesión REST " es técnicamente un oxímoron.

La autenticación RESTful significa enviar autenticación con cada solicitud porque no tiene estado. El ejemplo proporcionado por Drupal 8 core es el módulo de autenticación básica, que permite enviar credenciales de autenticación para una solicitud HTTP a través de la autenticación HTTP básica, dado a un usuario con permiso para acceder al contenido a través de GET.

Ejemplo RESTful

Rizo: curl -vvv -k -H "Authorization: Basic test:password" http://8.d8.local/node/1?_format=json

GET /node/1?_format=json HTTP/1.1
Host: 8.d8.local
User-Agent: curl/7.43.0
Accept: */*
Authorization: Basic test:password

Sin embargo, esto generalmente no es lo suficientemente bueno. Los simple_oauth y oauth módulos contrib proporcionan OAuth 2 y 1 de soporte, respectivamente., Con el que una solicitud HTTP se puede hacer con la autenticación OAuth tokens basado en el trabajo OAuth flujos describe en dichos módulos.

Pero la verdadera pregunta parece ser

¿Cómo inicio sesión a través de una API de servicios web?

No hay un módulo Drupal 8 estable para hacerlo, pero el módulo Servicios proporciona métodos para crear acciones no RESTful y acciones específicas como "inicio de sesión".

Lo siguiente funciona después de configurar un punto final llamado "api":

Rizo: curl -vvv -k -H "Content-Type: application/json" -H "Accept: application/json" -d '{"username": "test", "password": "password"}' http://8.d8.local/api/user/login

POST /api/user/login HTTP/1.1
Host: 8.d8.local
Accept: application/json
Content-Type: application/json
Content-Length: 44

{"username": "test", "password": "password"}

Esto devuelve la identificación y el nombre de la sesión JSON (también establecido en el encabezado Set-Cookie de la respuesta).

y también puede iniciar sesión con Jquery ajax call con el siguiente fragmento

$.ajax({
    url : "http://gttc.dd:8083/user/login",
    type : 'post',
    data : 'form_id=user_login_form&name=' + encodeURIComponent("username") + '&pass=' + encodeURIComponent("password"),
    dataType : 'json',
    error : function(data) {
            //error code
    },
    success : function(data) {
      console.log(data);
        //success code
    }
});
mradcliffe
fuente
Los servicios parecen geniales, sin embargo, el núcleo de Drupal está en mal estado en D8 IMO. Hay mucho más por venir.
niksmac
1
Desde Drupal 8.2 puede (y debe) usar el método descrito en drupal.stackexchange.com/a/221045/13237
andeersg
4

Versión Drupal Core: 8.x-4.x

Primero debe habilitar el servicio de inicio de sesión de usuario, esto se puede lograr de muchas maneras, prefiero usar el módulo REST UI .

Vaya a / admin / config / services / rest y active el recurso User Rest.

Una vez habilitado, puede ir a / admin / config / services / rest / resource / entity% 3Auser / edit haciendo clic en Editar junto al recurso de usuario . Asegúrese de habilitar el método GET .

ingrese la descripción de la imagen aquí

Ahora que tiene todo configurado, puede comenzar a usar el servicio ejecutando este comando en la terminal o usando cualquier aplicación para solicitudes curl como: clientes Postman y Restlet .

NOTA : El token CSRF se puede obtener de: / rest / session / token

curl -i -L -X POST \
  -H "Content-Type:application/json" \
  -H "Accept:application/json" \
  -H "X-CSRF-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
  -d \
     '{
       "name": "my_username",
       "pass": "my_password"
     }' \
'http://SITE-URL/user/login?_format=json'

Los objetos de retorno son los siguientes:

ÉXITO :

{
  "current_user": {
  "uid": "1",
    "roles": [
      "authenticated"
    ],
    "name": "Admin"
  },
  "csrf_token": "bbbbbbbbbbbbbbbbbbbbbbbbbb",
  "logout_token": "ccccccccccccccccccccccccc"
}

FALLO :

{
  "message":"Sorry, unrecognized username or password."
}
Mohammad AlQanneh
fuente
> Vaya a / admin / config / services / rest y active el recurso User Rest. Creo que no necesita habilitar el recurso de usuario para iniciar sesión con REST api. La habilitación de este recurso solo es necesaria si desea realizar la operación CRUD en la entidad Usuario. Puede iniciar sesión con la API de descanso como lo menciona @ tyler.frankenstein
MutantMahesh
2

Utilizo el inicio de sesión RESTFul personalizado en drupal 8 pero no con cookie. Es para una aplicación móvil y cada vez que necesito información, uso una autenticación simple:

Desde Drupal 8.2x necesitamos 2 archivos en un módulo:

rest.ressource.user.rest_ressource.yml en la carpeta config / install

langcode: en
status: true
dependencies:
  module:
    - basic_auth
id: user.rest_ressource
plugin_id: 'user_rest_ressource'
granularity: resource
configuration:
  methods:
    - GET
    - PATCH
  formats:
    - json
  authentication:
    - basic_auth

Puedes agregar más métodos como DELETE / POST

Entonces necesitamos el archivo

userRestRessource.php en src / Plugin / rest / resource

    <?php

    namespace Drupal\yourmodule\Plugin\rest\resource;

    use Drupal\Core\Session\AccountProxyInterface;
    use Drupal\rest\Plugin\ResourceBase;
    use Drupal\rest\ResourceResponse;
    use Symfony\Component\DependencyInjection\ContainerInterface;
    use Psr\Log\LoggerInterface;


    /**
     * Provides a resource to get view modes by entity and bundle.
     *
     * @RestResource(
     *   id = "user_rest_ressource",
     *   label = @Translation("User Rest"),
     *   uri_paths = {
     *     "canonical" = "/api/user/getInfo"
     *   }
     * )
     */
    class UserRestRessource extends ResourceBase {

      /**
       * A current user instance.
       *
       * @var \Drupal\Core\Session\AccountProxyInterface
       */
      protected $currentUser;

      /**
       * Constructs a Drupal\rest\Plugin\ResourceBase object.
       *
       * @param array $configuration
       *   A configuration array containing information about the plugin instance.
       * @param string $plugin_id
       *   The plugin_id for the plugin instance.
       * @param mixed $plugin_definition
       *   The plugin implementation definition.
       * @param array $serializer_formats
       *   The available serialization formats.
       * @param \Psr\Log\LoggerInterface $logger
       *   A logger instance.
       * @param \Drupal\Core\Session\AccountProxyInterface $current_user
       *   A current user instance.
       */
      public function __construct(
        array $configuration,
        $plugin_id,
        $plugin_definition,
        array $serializer_formats,
        LoggerInterface $logger,
        AccountProxyInterface $current_user) {
        parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);

        $this->currentUser = $current_user;

      }

      /**
       * {@inheritdoc}
       */
      public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
        return new static(
          $configuration,
          $plugin_id,
          $plugin_definition,
          $container->getParameter('serializer.formats'),
          $container->get('logger.factory')->get('yourmodulename'),
          $container->get('current_user')
        );
      }

      /**
       * Responds to GET requests.
       *
       * Returns a list of bundles for specified entity.
       *
       * @throws \Symfony\Component\HttpKernel\Exception\HttpException
       *   Throws exception expected.
       */
      public function get() {

          $uid=$this->currentUser->getAccount()->id();
          $role=$this->currentUser->getAccount()->getRoles(1);

//here you can add your custom code
 $responseResource=new ResourceResponse(
          array()

      );
        return $responseResource;
      }

        /**
         * Responds to PATCH requests.
         *
         * Returns a list of bundles for specified entity.
         *
         * @throws \Symfony\Component\HttpKernel\Exception\HttpException
         *   Throws exception expected.
         */
        public function patch(){

        }

    }

No olvide ir al derecho del usuario para aceptar el método GET / POST o cualquier cosa que haya agregado en su configuración.

Con eso puede crear cada archivo REST personalizado para cada entidad personalizada.

Y en mi js: no olvides llamar

yoursiteUrl / rest / session / token

para obtener token

$http({
            method: 'GET',
            url: 'siteUrl/api/user/getInfo?_format=json',
                          withCredentials:true,
                          headers: {
                                   'Content-Type': "application/hal+json",
                                   'X-CSRF-Token': token,
                                   'Authorization': 'Basic ' + btoa(user+':'+password),

                         },


                        }).then(function successCallback(response) {

                             return response;

                          }, function errorCallback(response) {
                              return false;

                          });
Kevin
fuente
2

Siguiendo la respuesta de @ tyler.frankenstein, si desea implementar un formulario de inicio de sesión con Ajax, puede usar, por ejemplo, jQuery.

1. Obtenga un token CSRF

Necesitamos hacer una solicitud POST al user/login punto final de la API de Drupal 8. Este punto final (considerado como un "método no seguro") requiere que envíe un token CSRF.

El primer paso es obtener este token enviando una solicitud AJAX al rest/session/tokenpunto final:

var getCsrfToken = function(callback) {
    $.get(Drupal.url('rest/session/token'))
        .done(function (data) {
            var csrfToken = data;
            callback(csrfToken);
        });
}

NÓTESE BIEN:

  • El callbackparámetro es una función de devolución de llamada que se llamará cuando se recupere el token CSRF
  • Usamos la Drupal.urlfunción para obtener la URL base del sitio

Este token debe enviarse con un X-CSRF-Tokenencabezado.

2. Iniciar sesión

Considere el siguiente HTML:

<form id="login" method="post" action="" accept-charset="UTF-8">
    <div class="input-field">
        <input id="edit-name" name="name" type="text" class="validate">
        <label for="edit-name">Username or email address</label>
    </div>
    <div class="input-field">
        <input id="edit-pass" name="pass" type="password" class="validate">
        <label for="edit-pass">Password</label>
    </div>
    <p><a href="{{ url('user.pass') }}">Forgot your password?</a></p>
    <button type="submit" class="btn btn-default btn-submit">Sign in</button>
</form>

... y el código jQuery correspondiente:

$('form#login').on('submit', function(e) {
    e.preventDefault();

    var inputUsername = $('#edit-name').val();
    var inputPassword = $('#edit-pass').val();

    if (inputUsername != '' && inputPassword != '') {
        getCsrfToken(function(csrfToken) {
            $.ajax({
                url: Drupal.url('user/login?_format=json'),
                type: 'POST',
                dataType: 'json',
                data: JSON.stringify({name: inputUsername, pass: inputPassword}),
                headers: {
                    'X-CSRF-Token': csrfToken
                },
            }).done(function(response) {
                if (response.current_user) {
                    console.log('The user is logged!');
                }
            }).fail(function(jqXHR, textStatus) {
                ...
            });
        });
    }
});

Este código ha sido probado con éxito con Drupal 8.3.

¡Espero que esto ayude!

Guicara
fuente
1

Sí, claro, hice un blog sobre cómo probarlo con cartero , y también otro sobre cómo configurar su sitio drupal .

En este proyecto , inicié sesión en Drupal con angular, utilizando el módulo Simple OAuth para el token.

ValRob
fuente