รูปแบบ REST ของผู้ใช้เข้าสู่ระบบ


13

ทุกคนมีการเข้าสู่ระบบ REST ใน 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

Drupal สนับสนุนการทำงานของจุดปลาย json สำหรับการตรวจสอบคุกกี้โดยดูจาก 8.2 คุณไม่จำเป็นต้องโพสต์แบบฟอร์มอีกต่อไป🎉

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 คุณใช้อะไรในการทดสอบการโทร ฉันมีปัญหานี้ก่อนที่จะใช้บุรุษไปรษณีย์เพราะมันได้รับคุกกี้ Chrome ของฉันและบอกว่าฉันลงชื่อเข้าใช้คุณสามารถทดสอบได้โดยออกจากระบบในเบราว์เซอร์และส่งคำขออีกครั้ง
Antero Duarte

12

นี่คือวิธีที่คุณสามารถเข้าสู่ระบบผ่าน JavaScript สำหรับ Drupal 8 REST:

Drupal 8.2 ขึ้นไป

  • โพสต์ :http://example.com/user/login?_format=json
  • ประเภทเนื้อหา :application/json
  • ข้อมูล :{ "name": "admin", "pass": "myPassword" }
  • คำตอบ :200 OK

สิ่งนี้จะเข้าสู่ระบบอย่างถูกต้องผ่านการตรวจสอบคุกกี้และส่งคืนผลลัพธ์ที่คล้ายกับสิ่งนี้:

{
  "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());
});

ก่อนที่จะ Drupal 8.2

  • โพสต์ :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 ดังนั้นจะไม่ส่งคืนสิ่งที่มีประโยชน์สำหรับคุณ แต่จะเข้าสู่ระบบอย่างถูกต้องผ่านการตรวจสอบคุกกี้


ดังนั้น HTML ที่ส่งคืนจึงเป็นสิ่งที่หลีกเลี่ยงไม่ได้?
niksmac

ณ จุดนี้ AFAIK ใช่ HTML หลีกเลี่ยงไม่ได้ ฉันคิดว่าสิ่งนี้จะได้รับการปรับปรุงให้ดีขึ้นเมื่อเวลาผ่านไปตัวอย่างเช่นยังไม่มีวิธีในการลงทะเบียนผู้ใช้ผ่าน REST แต่มีปัญหาเกิดขึ้น
tyler.frankenstein

มันไม่ทำงานสำหรับฉันจำเป็นต้องใช้การรับรองความถูกต้องเบื้องต้นด้วยหรือไม่
Yusef

FYI, JSON จะถูกส่งคืนในฐานะ Drupal 8.2 ดังนั้นจะไม่มีการส่งคืน HTML อีกต่อไป
tyler.frankenstein

8
  1. การร้องขอ HTTP ไม่ได้สงบใหม่ตามประเภทเนื้อหา
  2. "การเข้าสู่ระบบ REST " เป็นเทคนิคในการสนทนา

การรับรองความถูกต้อง RESTful หมายถึงการส่งการรับรองความถูกต้องกับแต่ละคำขอเพราะมันไร้สัญชาติ ตัวอย่างที่จัดทำโดย Drupal 8 core คือโมดูล Auth พื้นฐานซึ่งอนุญาตให้ส่งข้อมูลรับรองการตรวจสอบสิทธิ์สำหรับการร้องขอ HTTP ผ่านการรับรองความถูกต้อง HTTP พื้นฐานที่กำหนดให้ผู้ใช้ที่ได้รับอนุญาตให้เข้าถึงเนื้อหาผ่าน GET

ตัวอย่างสงบ

Curl: 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 กระแสที่อธิบายไว้ในโมดูลเหล่านั้น

แต่คำถามจริงน่าจะเป็น

ฉันจะลงชื่อเข้าใช้ผ่าน Web Services API ได้อย่างไร

ที่มีอยู่ไม่มั่นคง Drupal 8 โมดูลจะทำเช่นนั้น แต่บริการโมดูลมีวิธีการในการสร้างการกระทำที่ไม่สงบและการกระทำที่กำหนดเป้าหมายเช่น "เข้าสู่ระบบ"

การทำงานต่อไปนี้หลังจากตั้งค่าปลายทางที่ชื่อ "api":

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

ส่งคืน ID เซสชันและชื่อ JSON (ตั้งค่าในส่วนหัว Set-Cookie ของการตอบกลับด้วย)

และคุณยังสามารถเข้าสู่ระบบด้วยการโทร Jquery ajax ด้วยตัวอย่างต่อไปนี้

$.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 core ถูกทำให้วุ่นวายใน D8 IMO มีอีกมากที่จะมา
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และเปิดใช้งานทรัพยากรส่วนที่เหลือของผู้ใช้

เมื่อเปิดใช้งานแล้วคุณสามารถไปที่/ admin / config / services / rest / resource / entity% 3Auser / editโดยคลิกที่แก้ไขถัดจากทรัพยากรผู้ใช้ ตรวจสอบให้แน่ใจว่าได้เปิดใช้งานวิธีการGET

ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้คุณมีการตั้งค่าทุกอย่างคุณสามารถเริ่มใช้บริการได้โดยการเรียกใช้คำสั่งนี้ในเทอร์มินัลหรือโดยใช้แอปพลิเคชันสำหรับคำขอ curl เช่นไคลเอนต์PostmanและRestlet

หมายเหตุ : CSRF Token สามารถรับได้จาก: / 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และเปิดใช้งานทรัพยากรส่วนที่เหลือของผู้ใช้ ฉันคิดว่าคุณไม่จำเป็นต้องเปิดใช้งานทรัพยากรผู้ใช้เพื่อเข้าสู่ระบบด้วย REST api การเปิดใช้งานทรัพยากรนี้จำเป็นเฉพาะเมื่อคุณต้องการดำเนินการ CRUD บนเอนทิตีผู้ใช้ เข้าสู่ระบบสามารถทำได้ด้วยส่วนที่เหลือ api ดังกล่าวโดย @ tyler.frankenstein
MutantMahesh

2

ฉันใช้การเข้าสู่ระบบ RESTFul แบบกำหนดเองใน drupal 8 แต่ไม่ใช่กับคุกกี้ สำหรับแอพมือถือและทุกครั้งที่ฉันต้องการข้อมูลฉันใช้การรับรองความถูกต้องง่าย ๆ :

ตั้งแต่ 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 / 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(){

        }

    }

อย่าลืมที่จะไปที่ผู้ใช้ที่ถูกต้องสำหรับวิธีการรับ GET / POST หรือสิ่งที่คุณเพิ่มในการกำหนดค่าของคุณ

โดยที่คุณสามารถสร้างไฟล์ REST ที่กำหนดเองได้ทุกไฟล์สำหรับเอนทิตีที่กำหนดเองทุกรายการ

และใน js ของฉัน: อย่าลืมโทร

yoursiteUrl / ส่วนที่เหลือ / ครั้ง / โทเค็น

รับโทเค็น

$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ปลายทางของ Drupal 8 API จุดสิ้นสุดนี้ (ซึ่งถือว่าเป็น "วิธีที่ไม่ปลอดภัย") กำหนดให้คุณส่งโทเค็น 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 สำหรับโทเค็น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.