Вхід користувача у формат REST


13

Хтось має працюючий REST Login на Drupal 8?

Це те, що я спробував.

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

Він повертає мені HTML замість JSON .

Відповіді:


15

Починаючи з 8.2, Drupal підтримує кінцеві точки json для аутентифікації файлів cookie. Вам більше не потрібно розміщувати форму 🎉

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

Вихід буде мати вигляд

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

Запис змін: https://www.drupal.org/node/2720655

Інші методи аутентифікації: https://www.drupal.org/docs/8/core/modules/rest/using-other-authentication-protocols


Я не можу змусити це працювати, я отримую 403 "Цей маршрут можуть отримати доступ лише анонімні користувачі." дивно, оскільки я використовую REST, очевидно, не ввійшов
Jim smith

1
@jimsmith Що ви використовуєте для тестування дзвінка? У мене була ця проблема перед тим, як використовувати Postman, оскільки він отримував мої файли cookie Chrome і говорив, що я ввійшов. Ви можете перевірити це, увійшовши в браузер і відправивши запит ще раз
Antero Duarte,

12

Ось як можна увійти через JavaScript для Drupal 8 REST:

Drupal 8.2 і пізніше

  • POST :http://example.com/user/login?_format=json
  • Тип вмісту :application/json
  • Дані :{ "name": "admin", "pass": "myPassword" }
  • Відповідь :200 OK

Це буде належним чином увійти через аутентифікацію файлів cookie та поверне результат, подібний до цього:

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

Я створив модуль contrib під назвою jDrupal, що дозволяє дуже легко входити в JavaScript (серед іншого):

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

До Друпалу 8.2

  • POST :http://example.com/user/login
  • Тип вмісту :application/x-www-form-urlencoded
  • Дані :name=admin&pass=myPassword&form_id=user_login_form
  • Відповідь :200 OK | 303 See Other

Ви надсилатимете дані разом із URL-адресою як рядок запиту. У результаті вийде HTML, тому він не поверне вам нічого корисного, але він буде належним чином увійти через аутентифікацію файлів cookie.


Тож повернення HTML неминуче?
niksmac

На даний момент AFAIK, так HTML неминучий. Я думаю, що з часом це покращиться, оскільки, наприклад, ще немає способу зареєструвати користувача через REST, але проблема була зроблена.
tyler.frankenstein

це не працює для мене, чи потрібно також використовувати базову автентифікацію?
Юсеф

FYI, JSON повертається станом на Drupal 8.2, тому більше HTML не повертається.
tyler.frankenstein

8
  1. HTTP-запит не RESTful на основі типу вмісту.
  2. " REST Login " технічно є оксимороном.

RESTful аутентифікація означає надсилати автентифікацію з кожним запитом, оскільки вона є без стану. Приклад, наданий ядром Drupal 8, - це модуль Basic Auth, який дозволяє надсилати облікові дані автентифікації для HTTP-запиту через базову автентифікацію HTTP, надану користувачеві з дозволом на доступ до вмісту через GET.

ПРИКЛАДНИЙ приклад

Завиток: 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

Однак зазвичай це недостатньо добре. У simple_oauth і OAuth модулів CONTRIB забезпечують підтримку OAuth 2 і 1 відповідно., З допомогою якого запит HTTP , може бути зроблений з допомогою перевірки автентичності OAuth маркери на основі OAuth роботи потоків , описані в цих модулях.

Але, здається, справжнє питання

Як я можу ввійти через API веб-служб?

Існує не модуль стабільної Drupal 8 , щоб зробити це, але Services модуль надає методи для створіння не-RESTful дії і цілеспрямовані дії , такі як «вхід».

Після встановлення кінцевої точки під назвою "api" працює наступне:

Завиток: 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"}

Це повертає ідентифікатор і ім'я сесії JSON (також встановлено у заголовку Set-Cookie відповіді).

а також ви можете увійти за допомогою Jquery ajax call з наступним фрагментом

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

Послуги здаються крутими, проте ядро ​​Drupal заплутане в IMO D8. попереду ще багато.
niksmac

1
Оскільки Drupal 8.2 ви можете (і повинні) використовувати метод, описаний в drupal.stackexchange.com/a/221045/13237
andeersg

4

Версія Drupal Core: 8.x-4.x

Вам потрібно ввімкнути службу входу в систему спочатку, це може бути здійснено дуже багато способів, я вважаю за краще використовувати модуль REST UI

Перейдіть до / admin / config / services / rest та увімкніть ресурс User Rest.

Після його ввімкнення ви можете перейти до / admin / config / services / rest / resource / entitet% 3Auser / edit , натиснувши на кнопку Edit поруч із ресурсом користувача . Обов’язково ввімкніть метод GET .

введіть тут опис зображення

Тепер у вас є всі установки, ви можете почати користуватися послугою, виконавши цю команду в терміналі або за допомогою будь-якої програми для запитів локона , як: Листоноша і Restlet клієнтів.

ПРИМІТКА : Токен CSRF можна отримати з: / 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'

Об'єкти, що повертаються, наведені нижче:

УСПІХ :

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

Збій :

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

> Перейдіть до / admin / config / services / rest та ввімкніть ресурс User Rest. Я думаю, вам не потрібно вмикати Користувацький ресурс для входу в систему за допомогою REST api. Увімкнення цього ресурсу потрібно лише в тому випадку, якщо ви хочете виконати операцію CRUD в особі користувача. Увійти в систему можна за допомогою api відпочинку, як згадував @ tyler.frankenstein
MutantMahesh

2

Я використовую користувальницький логін RESTFul на drupal 8, але не з cookie. Це для мобільного додатку, і кожного разу, коли мені потрібна інформація, я використовую простий аутентифікат:

Оскільки Drupal 8.2x нам потрібні 2 файли в модулі:

rest.ressource.user.rest_ressource.yml у папці 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

Ви можете додати більше методу, як DELETE / POST

Тоді нам потрібен файл

userRestRessource.php в src / плагін / відпочинок / ресурс

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

        }

    }

Не забудьте перейти до права користувача, щоб прийняти метод GET / POST або що-небудь, що ви додали у конфігурацію.

Завдяки цьому ви можете створити кожен користувацький файл REST для кожної власної сутності.

І в моєму js: Не забувай зателефонувати

tvojeiteUrl / відпочинок / сесія / маркер

для отримання жетону

$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

Після відповіді @ tyler.frankenstein, якщо ви хочете реалізувати форму для входу з Ajax, ви можете, наприклад, використовувати jQuery.

1. Отримайте маркер CSRF

Нам потрібно зробити запит POST до user/loginкінцевої точки API Drupal 8. Ця кінцева точка (розглядається як "безпечний метод") вимагає надіслати маркер CSRF.

Перший крок - отримати цей маркер, надіславши запит AJAX до rest/session/tokenкінцевої точки:

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

Примітка:

  • callbackПараметр є функцію зворотного виклику , яка буде викликатися , коли маркер CSRF буде витягується
  • Ми використовуємо Drupal.urlфункцію для отримання базової URL-адреси сайту

Цей маркер слід надсилати із X-CSRF-Tokenзаголовком.

2. Вхід

Розглянемо наступний 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>

... і відповідний код 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) {
                ...
            });
        });
    }
});

Цей код було успішно протестовано на Drupal 8.3.

Я сподіваюся, що це допоможе тобі!


0

Так, я створив блог про те, як протестувати його з листоношею , а також про те, як налаштувати ваш drupal-сайт .

У цьому проекті я зробив логін для Drupal з кутовим, використовуючи модуль Simple OAuth для маркера.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.