Formato REST di accesso utente


13

Qualcuno ha un accesso REST funzionante su Drupal 8?

Questo è quello che ho provato.

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

Mi restituisce HTML anziché JSON .

Risposte:


15

A partire dalla versione 8.2, Drupal supporta endpoint json per l'autenticazione dei cookie. Non è più necessario inviare il modulo 🎉

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

L'output sarà simile

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

Registro delle modifiche: https://www.drupal.org/node/2720655

Altri metodi di autenticazione: https://www.drupal.org/docs/8/core/modules/rest/using-other-authentication-protocols


Non riesco a farlo funzionare, ottengo 403 "Questo percorso è accessibile solo a utenti anonimi." strano come sto usando REST ovviamente non connesso
Jim Smith

1
@jimsmith Cosa stai usando per testare la chiamata? Ho avuto questo problema prima di utilizzare Postman perché riceveva i miei cookie Chrome e diceva che avevo effettuato l'accesso. Puoi verificarlo disconnettendoti nel browser e inviando di nuovo la richiesta
Antero Duarte,

11

Ecco come è possibile accedere tramite JavaScript per Drupal 8 REST:

Drupal 8.2 e oltre

  • POST :http://example.com/user/login?_format=json
  • Tipo di contenuto :application/json
  • Dati :{ "name": "admin", "pass": "myPassword" }
  • Risposta :200 OK

Questo accederà correttamente tramite l'autenticazione dei cookie e restituirà un risultato simile al seguente:

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

Ho creato un modulo contrib chiamato jDrupal che rende molto facile il login con JavaScript (tra le altre cose):

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

Prima di Drupal 8.2

  • POST :http://example.com/user/login
  • Tipo di contenuto :application/x-www-form-urlencoded
  • Dati :name=admin&pass=myPassword&form_id=user_login_form
  • Risposta :200 OK | 303 See Other

Invierai i dati nell'URL come stringa di query. Il risultato sarà HTML, quindi non ti restituirà nulla di utile, ma accederà correttamente tramite l'autenticazione dei cookie.


Quindi restituire HTML è inevitabile?
Niksmac,

A questo punto AFAIK, sì, l'HTML è inevitabile. Immagino che questo verrà migliorato nel tempo, perché ad esempio non esiste ancora un modo per registrare un utente tramite REST, ma è stato riscontrato un problema.
Tyler.frankenstein,

non ha funzionato per me, è necessario utilizzare anche l'autenticazione di base?
Yusef,

Cordiali saluti, JSON viene restituito a partire da Drupal 8.2, quindi non viene più restituito HTML.
tyler.frankenstein,

8
  1. Una richiesta HTTP non è RESTful in base al tipo di contenuto.
  2. " REST Login " è tecnicamente un ossimoro.

Autenticazione RESTful significa inviare l'autenticazione con ogni richiesta perché è apolide. L'esempio fornito da Drupal 8 core è il modulo di autenticazione di base, che consente di inviare credenziali di autenticazione per una richiesta HTTP tramite l'autenticazione HTTP di base, a cui un utente è autorizzato ad accedere al contenuto tramite GET.

Esempio RESTful

Arricciare: 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

Tuttavia, questo di solito non è abbastanza buono. I moduli simple_oauth e oauth contrib forniscono rispettivamente il supporto OAuth 2 e 1., Con cui è possibile effettuare una richiesta HTTP con token di autenticazione OAuth basati sui flussi di lavoro OAuth descritti in tali moduli.

Ma la vera domanda sembra essere

Come si accede tramite un'API dei servizi Web?

Non esiste un modulo Drupal 8 stabile per farlo, ma il modulo Servizi fornisce metodi per creare azioni non RESTful e azioni mirate come "login".

Quanto segue funziona dopo aver impostato un endpoint chiamato "api":

Arricciare: 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"}

Ciò restituisce ID sessione JSON e nome (anche impostato nell'intestazione Set-Cookie della risposta).

e puoi anche accedere con la chiamata ajax di Jquery con il seguente frammento

$.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
    }
});

I servizi sembrano interessanti, tuttavia il core di Drupal è incasinato in D8 IMO. c'è molto di più a venire.
Niksmac,

1
Da Drupal 8.2 puoi (e dovresti) usare il metodo descritto in drupal.stackexchange.com/a/221045/13237
andeersg

4

Versione Drupal Core: 8.x-4.x

Devi prima abilitare il servizio di accesso utente, questo può essere realizzato in così tanti modi, preferisco usare il modulo UI REST .

Vai su / admin / config / services / rest e abilita la risorsa User Rest.

Una volta abilitato, puoi andare su / admin / config / services / rest / resource / entity% 3Auser / edit facendo clic su Modifica accanto alla risorsa Utente . Assicurati di abilitare il metodo GET .

inserisci qui la descrizione dell'immagine

Ora hai tutto configurato, puoi iniziare a usare il servizio eseguendo questo comando nel terminale o usando qualsiasi applicazione per richieste di arricciatura come: client Postman e Restlet .

NOTA : il token CSRF può essere ottenuto da: / 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'

Gli oggetti di ritorno sono i seguenti:

SUCCESSO :

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

GUASTO :

{
  "message":"Sorry, unrecognized username or password."
}

> Vai a / admin / config / services / rest e abilita la risorsa User Rest. Penso che non sia necessario abilitare la risorsa utente per accedere con API REST. L'abilitazione di questa risorsa è necessaria solo se si desidera eseguire un'operazione CRUD sull'entità utente. L'accesso può essere effettuato con api di riposo, come indicato da @ tyler.frankenstein
MutantMahesh

2

Uso l'accesso RESTFul personalizzato su drupal 8 ma non con i cookie. È per un'app mobile e ogni volta che ho bisogno di informazioni, utilizzo un semplice Authenticate:

Da Drupal 8.2x abbiamo bisogno di 2 file in un modulo:

rest.ressource.user.rest_ressource.yml nella cartella 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

Puoi aggiungere altri metodi come DELETE / POST

Quindi abbiamo bisogno del file

userRestRessource.php in 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(){

        }

    }

Non dimenticare di andare all'utente giusto per accettare il metodo GET / POST o qualsiasi cosa tu abbia aggiunto nella tua configurazione.

Con ciò puoi creare ogni file REST personalizzato per ogni entità personalizzata.

E nel mio js: non dimenticare di chiamare

yoursiteUrl / resto / session / gettone

per ottenere 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;

                          });

2

Seguendo la risposta di @ tyler.frankenstein, se si desidera implementare un modulo di accesso con Ajax, è possibile ad esempio utilizzare jQuery.

1. Ottieni un token CSRF

Dobbiamo presentare una richiesta POST user/loginall'endpoint dell'API Drupal 8. Questo endpoint (considerato come un "metodo non sicuro") richiede l'invio di un token CSRF.

Il primo passo è ottenere questo token inviando una richiesta AJAX rest/session/tokenall'endpoint:

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

NB:

  • Il callbackparametro è una funzione di callback che verrà chiamata quando verrà recuperato il token CSRF
  • Usiamo la Drupal.urlfunzione per ottenere l'URL di base del sito

Questo token deve essere inviato con X-CSRF-Tokenun'intestazione.

2. Login

Considera il seguente 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>

... e il corrispondente codice jQuery:

$('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) {
                ...
            });
        });
    }
});

Questo codice è stato testato con successo con Drupal 8.3.

Spero che questo ti possa aiutare!


1

Sì certo, ho creato un blog su come testarlo con postino , e anche un altro su come configurare il tuo sito drupal .

In questo progetto ho effettuato un login per Drupal con angolare, usando il modulo OAuth semplice per il token.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.