Định dạng người dùng đăng nhập REST


13

Có ai có Đăng nhập REST hoạt động trên Drupal 8 không?

Đây là những gì tôi đã cố gắng.

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

Nó trả về cho tôi HTML thay vì JSON .

Câu trả lời:


15

Bắt đầu từ 8.2, Drupal hỗ trợ các điểm cuối json để xác thực Cookie. Bạn không cần phải đăng mẫu nữa

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

Đầu ra sẽ như thế nào

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

Thay đổi hồ sơ: https://www.drupal.org/node/2720655

Các phương thức xác thực khác: https://www.drupal.org/docs/8/core/modules/rest/USE-other-authentication-prot Protocol


Tôi không thể làm việc này, tôi nhận được 403 "Tuyến này chỉ có thể được truy cập bởi người dùng ẩn danh." lạ vì tôi đang sử dụng REST rõ ràng không đăng nhập
jim smith

1
@jimsmith Bạn đang sử dụng gì để kiểm tra cuộc gọi? Tôi đã gặp vấn đề này trước khi sử dụng Postman vì nó đã nhận được Chrome Cookies của tôi và nói rằng tôi đã đăng nhập. Bạn có thể kiểm tra điều này bằng cách đăng xuất khỏi trình duyệt và gửi lại yêu cầu
Antero Duarte

11

Đây là cách bạn có thể đăng nhập qua JavaScript cho Drupal 8 REST:

Drupal 8.2 và hơn thế nữa

  • BÀI ĐĂNG :http://example.com/user/login?_format=json
  • Kiểu nội dung :application/json
  • Dữ liệu :{ "name": "admin", "pass": "myPassword" }
  • Trả lời :200 OK

Điều này sẽ đăng nhập đúng cách thông qua xác thực cookie và trả về kết quả tương tự như sau:

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

Tôi đã tạo một mô-đun đóng góp có tên là jDrupal giúp đăng nhập bằng JavaScript rất dễ dàng (trong số những thứ khác):

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

Trước Drupal 8.2

  • BÀI ĐĂNG :http://example.com/user/login
  • Kiểu nội dung :application/x-www-form-urlencoded
  • Dữ liệu :name=admin&pass=myPassword&form_id=user_login_form
  • Trả lời :200 OK | 303 See Other

Bạn sẽ gửi dữ liệu trong URL dưới dạng chuỗi truy vấn. Kết quả sẽ là HTML, vì vậy nó sẽ không trả lại bất cứ điều gì hữu ích cho bạn, nhưng nó sẽ đăng nhập đúng cách thông qua xác thực cookie.


Vì vậy, trả lại HTML là không thể tránh khỏi?
niksmac

Tại thời điểm này AFAIK, có HTML là không thể tránh khỏi. Tôi tưởng tượng điều này sẽ được cải thiện theo thời gian, vì ví dụ, chưa có cách nào để đăng ký người dùng thông qua REST, nhưng một vấn đề đã được thực hiện.
tyler.frankenstein

nó không hoạt động với tôi, có bắt buộc phải sử dụng Xác thực cơ bản không?
Yusef

FYI, JSON được trả về kể từ Drupal 8.2, do đó không có thêm HTML nào được trả về.
tyler.frankenstein

8
  1. Yêu cầu HTTP không phải là RESTful dựa trên Kiểu nội dung.
  2. " Đăng nhập REST " về mặt kỹ thuật là một oxymoron.

Xác thực RESTful có nghĩa là gửi xác thực với mỗi yêu cầu vì nó không trạng thái. Ví dụ được cung cấp bởi lõi Drupal 8 là mô-đun Auth cơ bản, cho phép gửi thông tin xác thực cho yêu cầu HTTP thông qua Xác thực HTTP cơ bản được cung cấp cho người dùng có quyền truy cập Nội dung qua GET.

Ví dụ RESTful

Xoăn: 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

Tuy nhiên điều này thường không đủ tốt. Đơn giản_oauthoauth mô-đun contrib cung cấp hỗ trợ OAuth 2 và 1 tương ứng., Trong đó yêu cầu HTTP có thể được thực hiện với mã thông báo xác thực OAuth dựa trên các luồng công việc OAuth được mô tả trong các mô-đun đó.

Nhưng câu hỏi thực sự có vẻ là

Làm cách nào để tôi đăng nhập thông qua API dịch vụ web?

Không có mô-đun Drupal 8 ổn định để làm như vậy, nhưng Dịch vụ mô-đun cung cấp các phương thức để tạo các hành động phi RESTful và các hành động được nhắm mục tiêu như "đăng nhập".

Các hoạt động sau đây sau khi thiết lập một điểm cuối được gọi là "api":

Xoăn: 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"}

Điều này trả về id và tên phiên JSON (cũng được đặt trong tiêu đề Set-Cookie của phản hồi).

và bạn cũng có thể đăng nhập bằng cuộc gọi ajax của Jquery với đoạn trích sau

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

Các dịch vụ có vẻ hay, tuy nhiên lõi Drupal bị rối trong D8 IMO. còn rất nhiều điều nữa sẽ đến
niksmac

1
Kể từ Drupal 8.2, bạn có thể (và nên) sử dụng phương pháp được mô tả trong drupal.stackexchange.com/a/221045/13237
andeerg

4

Phiên bản lõi Drupal: 8.x-4.x

Bạn cần kích hoạt dịch vụ đăng nhập người dùng trước tiên, điều này có thể được thực hiện bằng nhiều cách, tôi thích sử dụng mô-đun UI UI .

Truy cập / admin / config / services / rest và bật tài nguyên User Rest.

Sau khi kích hoạt, bạn có thể truy cập / admin / config / services / rest / resource / entity% 3Auser / chỉnh sửa bằng cách nhấp vào Chỉnh sửa bên cạnh tài nguyên Người dùng . Đảm bảo bật phương thức GET .

nhập mô tả hình ảnh ở đây

Bây giờ bạn đã thiết lập mọi thứ, bạn có thể bắt đầu sử dụng dịch vụ bằng cách chạy lệnh này trong thiết bị đầu cuối hoặc bằng cách sử dụng bất kỳ ứng dụng nào cho các yêu cầu cuộn tròn như: PostmanRestlet client.

LƯU Ý : Mã thông báo CSRF có thể được lấy từ: / 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'

Các đối tượng trả lại như sau:

THÀNH CÔNG :

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

THẤT ​​BẠI :

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

> Chuyển đến / admin / config / services / rest và bật tài nguyên User Rest. Tôi nghĩ rằng bạn không cần phải kích hoạt tài nguyên Người dùng để đăng nhập bằng REST api. Việc kích hoạt tài nguyên này chỉ được yêu cầu nếu bạn muốn thực hiện thao tác CRUD trên thực thể Người dùng. Đăng nhập có thể đạt được với phần còn lại api như được đề cập bởi @ tyler.frankenstein
MutantMahesh

2

Tôi sử dụng đăng nhập RESTFul tùy chỉnh trên drupal 8 nhưng không phải với cookie. Đó là cho một ứng dụng di động và mỗi khi tôi cần thông tin, tôi sử dụng một Xác thực đơn giản:

Vì Drupal 8.2x, chúng tôi cần 2 tệp trong một mô-đun:

rest.ressource.user.rest_ressource.yml trong thư mục 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

Bạn có thể thêm phương thức khác như XÓA / POST

Sau đó, chúng tôi cần các tập tin

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

        }

    }

Đừng quên truy cập quyền người dùng để chấp nhận phương thức GET / POST hoặc bất cứ điều gì bạn đã thêm vào cấu hình của mình.

Với điều đó, bạn có thể tạo mọi tệp REST tùy chỉnh cho mọi thực thể tùy chỉnh.

Và trong js của tôi: Đừng quên gọi

yoursiteUrl / rest / session / token

để nhận mã thông báo

$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

Theo câu trả lời của @ tyler.frankenstein, nếu bạn muốn triển khai một biểu mẫu đăng nhập với Ajax, ví dụ bạn có thể sử dụng jQuery.

1. Nhận mã thông báo CSRF

Chúng tôi cần phải thực hiện một yêu cầu POST cho user/login điểm cuối của API Drupal 8. Điểm cuối này (được coi là "phương pháp không an toàn") yêu cầu bạn gửi mã thông báo CSRF.

Bước đầu tiên là nhận mã thông báo này bằng cách gửi yêu cầu AJAX đến rest/session/tokenđiểm cuối:

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

Lưu ý:

  • Các callback tham số là một hàm callback sẽ được gọi khi CSRF token sẽ được lấy
  • Chúng tôi sử dụng Drupal.urlchức năng để lấy URL cơ sở của trang web

Mã thông báo này phải được gửi với X-CSRF-Token tiêu đề.

2. Đăng nhập

Hãy xem xét HTML sau:

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

... và mã jQuery tương ứng:

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

Mã này đã được thử nghiệm thành công với Drupal 8.3.

Tôi hy vọng điều này sẽ giúp bạn!


1

Vâng chắc chắn, tôi đã tạo một blog về cách kiểm tra nó với người đưa thư , và một blog khác về cách định cấu hình trang web drupal của bạn .

Trong dự án này, tôi đã đăng nhập vào Drupal với góc cạnh, sử dụng mô-đun OAuth đơn giản cho mã thông báo.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.