Format REST logowania użytkownika

13

Czy ktoś ma działające logowanie REST na Drupal 8?

Właśnie tego próbowałem.

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

Zwraca mi HTML zamiast JSON .

niksmac
źródło

Odpowiedzi:

15

Zaczynając od wersji 8.2, Drupal obsługuje punkty końcowe json do uwierzytelniania plików cookie. Nie musisz już publikować formularza 🎉

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

Wyjście będzie wyglądać

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

Zmień zapis: https://www.drupal.org/node/2720655

Inne metody uwierzytelniania: https://www.drupal.org/docs/8/core/modules/rest/using-other-authentication-protocols

kalabro
źródło
Nie mogę tego uruchomić, otrzymuję 403 „Dostęp do tej trasy mają tylko anonimowi użytkownicy”. dziwne, ponieważ korzystam z REST, oczywiście nie jestem zalogowany
Jim Smith
1
@jimsmith Czego używasz do testowania połączenia? Miałem ten problem przed użyciem Postmana, ponieważ pobierałem moje Chrome Cookies i stwierdzałem, że jestem zalogowany. Możesz to sprawdzić, wylogowując się w przeglądarce i wysyłając zapytanie ponownie
Antero Duarte,
12

Oto jak możesz zalogować się przez JavaScript dla Drupal 8 REST:

Drupal 8.2 i nowsze

  • POST :http://example.com/user/login?_format=json
  • Typ zawartości :application/json
  • Dane :{ "name": "admin", "pass": "myPassword" }
  • Odpowiedź :200 OK

Spowoduje to prawidłowe logowanie za pomocą uwierzytelniania plików cookie i zwróci wynik podobny do tego:

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

Stworzyłem moduł contrib o nazwie jDrupal, który bardzo ułatwia logowanie za pomocą JavaScript (między innymi):

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

Przed Drupalem 8.2

  • POST :http://example.com/user/login
  • Typ zawartości :application/x-www-form-urlencoded
  • Dane :name=admin&pass=myPassword&form_id=user_login_form
  • Odpowiedź :200 OK | 303 See Other

Prześlesz dane wraz z adresem URL jako ciąg zapytania. Rezultatem będzie HTML, więc nie zwróci ci niczego przydatnego, ale poprawnie zaloguje się za pomocą uwierzytelnienia cookie.

tyler.frankenstein
źródło
Czy więc zwrot HTML jest nieunikniony?
niksmac
W tym momencie AFAIK, tak HTML jest nieunikniony. Wyobrażam sobie, że z czasem ulegnie to poprawie, ponieważ na przykład nie ma jeszcze sposobu na zarejestrowanie użytkownika przez REST, ale wystąpił problem.
tyler.frankenstein
dla mnie to nie zadziałało, czy wymagane jest również użycie Podstawowego uwierzytelnienia?
Yusef,
Do Twojej wiadomości, JSON jest zwracany od wersji Drupal 8.2, więc nie jest już zwracany HTML.
tyler.frankenstein
8
  1. Żądanie HTTP nie jest RESTful oparte na typie treści.
  2. Logowanie REST ” jest technicznie oksymoronem.

Uwierzytelnianie RESTful oznacza wysyłanie uwierzytelnienia przy każdym żądaniu, ponieważ jest ono bezstanowe. Przykładem dostarczonym przez rdzeń Drupal 8 jest moduł Basic Auth, który umożliwia wysyłanie poświadczeń uwierzytelnienia dla żądania HTTP za pośrednictwem podstawowego uwierzytelniania HTTP, pod warunkiem, że użytkownik ma uprawnienia dostępu do treści za pośrednictwem GET.

RESTful Przykład

Kędzior: 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

Jednak zwykle nie jest to wystarczająco dobre. W simple_oauth i oauth moduły contrib zapewnić OAuth 2 i 1, odpowiednio, wsparcie., Przy którym żądanie HTTP może być wykonana z uwierzytelniania OAuth żetony na podstawie prac OAuth pieniężnych opisane w tych modułów.

Ale prawdziwe pytanie wydaje się być

Jak zalogować się przez interfejs API usług internetowych?

Nie ma do tego stabilnego modułu Drupal 8, ale moduł Usługi zapewnia metody tworzenia akcji innych niż RESTful oraz akcji ukierunkowanych, takich jak „logowanie”.

Następujące czynności działają po skonfigurowaniu punktu końcowego o nazwie „api”:

Kędzior: 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"}

Zwraca identyfikator i nazwę sesji JSON (również ustawione w nagłówku Set-Cookie odpowiedzi).

a także możesz zalogować się za pomocą wywołania Jquery ajax za pomocą następującego fragmentu kodu

$.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
źródło
Usługi wydają się fajne, jednak rdzeń Drupala jest zawalony w D8 IMO. jeszcze wiele więcej.
niksmac
1
Od wersji Drupal 8.2 możesz (i powinieneś) skorzystać z metody opisanej w drupal.stackexchange.com/a/221045/13237
andeersg
4

Wersja Drupal Core: 8.x-4.x

Najpierw musisz włączyć usługę logowania użytkownika, można to zrobić na wiele sposobów, wolę używać modułu interfejsu użytkownika REST .

Przejdź do / admin / config / services / rest i włącz zasób User Rest.

Po włączeniu możesz przejść do / admin / config / services / rest / resource / entity% 3Auser / edit , klikając Edytuj obok zasobu użytkownika . Pamiętaj, aby włączyć metodę GET .

wprowadź opis zdjęcia tutaj

Teraz, gdy masz już wszystko skonfigurowane, możesz zacząć korzystać z usługi, uruchamiając to polecenie w terminalu lub używając dowolnej aplikacji do wysyłania żądań curl, takich jak: klienci Postman i Restlet .

UWAGA : Token CSRF można uzyskać z: / 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'

Obiekty zwracane są jak poniżej:

SUKCES :

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

AWARIA :

{
  "message":"Sorry, unrecognized username or password."
}
Mohammad AlQanneh
źródło
> Przejdź do / admin / config / services / rest i włącz zasób User Rest. Myślę, że nie trzeba włączać zasobu użytkownika, aby zalogować się przy użyciu interfejsu API REST. Włączenie tego zasobu jest wymagane tylko wtedy, gdy chcesz wykonać operację CRUD na encji użytkownika. Zaloguj się można uzyskać za pomocą interfejsu API odpoczynku, jak wspomniano przez @ tyler.frankenstein
MutantMahesh
2

Używam niestandardowego logowania RESTFul na drupal 8, ale nie z cookie. Jest to aplikacja mobilna i za każdym razem, gdy potrzebuję informacji, używam prostego uwierzytelnienia:

Od Drupala 8.2x potrzebujemy 2 plików w module:

rest.ressource.user.rest_ressource.yml w folderze 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

Możesz dodać więcej metod, takich jak DELETE / POST

Następnie potrzebujemy pliku

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

        }

    }

Nie zapomnij przejść do prawa użytkownika, aby zaakceptować metodę GET / POST lub cokolwiek, co dodałeś do swojej konfiguracji.

Dzięki temu możesz utworzyć każdy niestandardowy plik REST dla każdego niestandardowego elementu.

I w moim js: Nie zapomnij zadzwonić

yoursiteUrl / rest / session / token

po 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
źródło
2

Po odpowiedzi na @ tyler.frankenstein, jeśli chcesz wdrożyć formularz logowania w Ajax, możesz na przykład użyć jQuery.

1. Zdobądź token CSRF

Musimy złożyć żądanie POST do user/loginpunktu końcowego interfejsu API Drupal 8. Ten punkt końcowy (uważany za „niebezpieczną metodę”) wymaga wysłania tokenu CSRF.

Pierwszym krokiem jest zdobycie tego tokena, wysyłając żądanie AJAX do rest/session/tokenpunktu końcowego:

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

NB:

  • Ten callbackparametr jest funkcją wywołania zwrotnego, która zostanie wywołana, gdy token CSRF zostanie pobrany
  • Używamy tej Drupal.urlfunkcji, aby uzyskać podstawowy adres URL witryny

Ten token należy wysłać z X-CSRF-Tokennagłówkiem.

2. Zaloguj się

Rozważ następujący kod 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>

... i odpowiedni kod 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) {
                ...
            });
        });
    }
});

Ten kod został pomyślnie przetestowany w Drupal 8.3.

Mam nadzieję, że to Ci pomoże!

Guicara
źródło
0

Tak, oczywiście, stworzyłem blog o tym, jak przetestować go z listonoszem , a także kolejny blog o tym , jak skonfigurować swoją witrynę drupal .

W tym projekcie zalogowałem się do Drupala za pomocą angulara, używając prostego modułu OAuth dla tokena.

ValRob
źródło