Benutzeranmeldung im REST-Format

13

Hat jemand ein funktionierendes REST-Login für Drupal 8?

Das habe ich versucht.

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

Es gibt mir HTML anstelle von JSON zurück .

niksmac
quelle

Antworten:

14

Ab Version 8.2 unterstützt Drupal JSON-Endpunkte für die Cookie-Authentifizierung. Sie müssen das Formular nicht mehr posten 🎉

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

Die Ausgabe wird so aussehen

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

Datensatz ändern: https://www.drupal.org/node/2720655

Andere Authentifizierungsmethoden: https://www.drupal.org/docs/8/core/modules/rest/using-other-authentication-protocols

kalabro
quelle
Ich kann das nicht zum Laufen bringen, ich bekomme 403 "Auf diese Route können nur anonyme Benutzer zugreifen." seltsam, da ich REST benutze offensichtlich nicht eingeloggt
Jim Smith
1
@jimsmith Mit was testen Sie den Anruf? Ich hatte dieses Problem vor der Verwendung von Postman, weil meine Chrome-Cookies abgerufen und gemeldet wurden, dass ich angemeldet war. Sie können dies testen, indem Sie sich im Browser abmelden und die Anfrage erneut senden
Antero Duarte,
11

So können Sie sich über JavaScript für Drupal 8 REST anmelden:

Drupal 8.2 und höher

  • POST :http://example.com/user/login?_format=json
  • Inhaltstyp :application/json
  • Daten :{ "name": "admin", "pass": "myPassword" }
  • Antwort :200 OK

Dies wird sich ordnungsgemäß über die Cookie-Authentifizierung anmelden und ein Ergebnis ähnlich dem folgenden zurückgeben:

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

Ich habe ein Contrib-Modul mit dem Namen jDrupal erstellt , mit dem Sie sich (unter anderem) ganz einfach mit JavaScript anmelden können:

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

Vor Drupal 8.2

  • POST :http://example.com/user/login
  • Inhaltstyp :application/x-www-form-urlencoded
  • Daten :name=admin&pass=myPassword&form_id=user_login_form
  • Antwort :200 OK | 303 See Other

Sie senden die Daten in der URL als Abfragezeichenfolge. Das Ergebnis ist HTML, sodass es Ihnen nichts Nützliches zurückgibt, sich jedoch ordnungsgemäß über die Cookie-Authentifizierung anmeldet.

tyler.frankenstein
quelle
Eine Rückkehr zu HTML ist also unvermeidlich?
Niksmac
Zu diesem Zeitpunkt ist AFAIK, ja HTML unvermeidlich. Ich würde mir vorstellen, dass dies im Laufe der Zeit verbessert wird, da es beispielsweise noch keine Möglichkeit gibt, einen Benutzer über REST zu registrieren, aber ein Problem vorliegt.
tyler.frankenstein
Es hat bei mir nicht funktioniert. Wird auch die Standardauthentifizierung benötigt?
Jusef
Zu Ihrer Information, JSON wird ab Drupal 8.2 zurückgegeben, sodass kein HTML mehr zurückgegeben wird.
tyler.frankenstein
8
  1. Eine HTTP-Anforderung ist basierend auf dem Inhaltstyp nicht REST-fähig.
  2. " REST Login " ist technisch gesehen ein Oxymoron.

RESTful-Authentifizierung bedeutet, dass bei jeder Anforderung eine Authentifizierung gesendet wird, da diese statusfrei ist. Das von Drupal 8 Core bereitgestellte Beispiel ist das Basic Auth-Modul, mit dem Authentifizierungsdaten für eine HTTP-Anforderung über die Basic HTTP-Authentifizierung gesendet werden können, wenn ein Benutzer die Berechtigung hat, über GET auf Inhalte zuzugreifen.

RESTvolles Beispiel

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

Dies ist jedoch in der Regel nicht gut genug. Das simple_oauth und oauth Module contrib bieten OAuth 2 bzw. 1-Unterstützung, mit denen eine HTTP-Anforderung mit OAuth-Authentifizierungstoken basierend auf den in diesen Modulen beschriebenen OAuth-Arbeitsabläufen durchgeführt werden kann.

Aber die eigentliche Frage scheint zu sein

Wie melde ich mich über eine Web Services-API an?

Dafür gibt es kein stabiles Drupal 8-Modul, sondern die Dienste Modul bietet Methoden zum Erstellen von nicht-REST-fähigen Aktionen und gezielten Aktionen wie "Login".

Nach dem Einrichten eines Endpunkts mit dem Namen "api" funktioniert Folgendes:

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

Dies gibt die ID und den Namen der JSON-Sitzung zurück (auch im Set-Cookie-Header der Antwort festgelegt).

und Sie können sich auch mit Jquery Ajax Call mit folgendem Snippet anmelden

$.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
quelle
Dienstleistungen scheinen cool, aber Drupal-Kern ist in D8 IMO durcheinander. es kommt noch viel mehr.
Niksmac
1
Seit Drupal 8.2 können (und sollten) Sie die in drupal.stackexchange.com/a/221045/13237
andeersg
4

Drupal Core-Version: 8.x-4.x

Sie müssen als Erstes den Benutzeranmeldedienst aktivieren. Dies kann auf so viele Arten erfolgen, dass ich die Verwendung des REST-UI- Moduls bevorzuge .

Gehen Sie zu / admin / config / services / rest und aktivieren Sie die Ressource User Rest.

Sobald es aktiviert ist, können Sie zu / admin / config / services / rest / resource / entity% 3Auser / edit gehen, indem Sie neben der Benutzerressource auf Edit klicken . Stellen Sie sicher, dass die GET- Methode aktiviert ist .

Bildbeschreibung hier eingeben

Nachdem Sie alle Einstellungen vorgenommen haben, können Sie den Dienst verwenden, indem Sie diesen Befehl im Terminal ausführen oder eine beliebige Anwendung für Curl-Anforderungen verwenden, z. B . : Postbote und Restlet Kunden.

HINWEIS : CSRF-Token erhalten Sie unter: / 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'

Die Rückgabeobjekte sind wie folgt:

ERFOLG :

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

FEHLER :

{
  "message":"Sorry, unrecognized username or password."
}
Mohammad AlQanneh
quelle
> Gehen Sie zu / admin / config / services / rest und aktivieren Sie die Ressource User Rest. Ich denke, Sie müssen die Benutzerressource nicht aktivieren, um sich mit der REST-API anzumelden. Die Aktivierung dieser Ressource ist nur erforderlich, wenn Sie eine CRUD-Operation für die Benutzerentität ausführen möchten. Die Anmeldung kann mit rest api erfolgen, wie von @ tyler.frankenstein
MutantMahesh
2

Ich benutze benutzerdefinierte RESTFul Login auf Drupal 8, aber nicht mit Cookie. Es ist für eine mobile App und jedes Mal, wenn ich Informationen benötige, verwende ich eine einfache Authentifizierung:

Seit Drupal 8.2x benötigen wir 2 Dateien in einem Modul:

rest.ressource.user.rest_ressource.yml im Ordner 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

Sie können weitere Methoden wie DELETE / POST hinzufügen

Dann brauchen wir die Datei

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(){

        }

    }

Vergiss nicht, zum Benutzerrecht zu gehen, um die Methode GET / POST oder etwas anderes zu akzeptieren, das du in deiner Konfiguration hinzugefügt hast.

Damit können Sie jede benutzerdefinierte REST-Datei für jede benutzerdefinierte Entität erstellen.

Und in meinem js: Vergiss nicht anzurufen

yoursiteUrl / rest / session / token

für get 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
quelle
2

Wenn Sie nach der Antwort von @ tyler.frankenstein ein Anmeldeformular mit Ajax implementieren möchten, können Sie beispielsweise jQuery verwenden.

1. Holen Sie sich ein CSRF-Token

Wir müssen eine POST-Anfrage an die senden user/login Endpunkt der Drupal 8-API senden. Für diesen Endpunkt (als "nicht sichere Methode" betrachtet) müssen Sie ein CSRF-Token senden.

Der erste Schritt besteht darin, dieses Token durch Senden einer AJAX-Anforderung an den rest/session/tokenEndpunkt abzurufen:

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

NB:

  • Der callbackParameter ist eine Rückruffunktion, die aufgerufen wird, wenn das CSRF-Token abgerufen wird
  • Wir verwenden die Drupal.urlFunktion, um die Basis-URL der Site zu erhalten

Dieses Token sollte mit einem X-CSRF-TokenHeader gesendet werden.

2. Login

Betrachten Sie das folgende 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>

... und den entsprechenden jQuery-Code:

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

Dieser Code wurde erfolgreich mit Drupal 8.3 getestet.

Ich hoffe, dies wird dir helfen!

Guicara
quelle
1

Ja klar, ich habe ein Blog darüber erstellt, wie man es mit dem Postboten testet , und ein weiteres, wie man seine Drupal-Site konfiguriert .

In diesem Projekt habe ich mich für Drupal mit Angular mit dem Simple OAuth-Modul für das Token angemeldet.

ValRob
quelle