Format REST login pengguna


13

Adakah yang punya REST Login yang berfungsi di Drupal 8?

Ini yang saya coba.

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

Ini mengembalikan saya HTML daripada JSON .

Jawaban:


15

Menatap dari 8.2, Drupal mendukung titik akhir json untuk otentikasi Cookie. Anda tidak perlu mengirim formulir lagi 🎉

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

Output akan terlihat seperti

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

Ubah catatan: https://www.drupal.org/node/2720655

Metode otentikasi lainnya: https://www.drupal.org/docs/8/core/modules/rest/using-other-authentication-protocols


Saya tidak dapat mengaktifkan ini, saya mendapatkan 403 "Rute ini hanya dapat diakses oleh pengguna anonim." aneh karena saya menggunakan REST jelas tidak masuk
jim smith

1
@jimsmith Apa yang Anda gunakan untuk menguji panggilan? Saya pernah mengalami masalah ini sebelum menggunakan tukang pos karena mendapatkan Chrome Cookie saya dan mengatakan saya sudah masuk. Anda dapat mengujinya dengan logout di browser dan mengirim permintaan lagi
Antero Duarte

11

Berikut cara Anda dapat masuk melalui JavaScript untuk Drupal 8 REST:

Drupal 8.2 dan seterusnya

  • POST :http://example.com/user/login?_format=json
  • Jenis konten :application/json
  • Data :{ "name": "admin", "pass": "myPassword" }
  • Tanggapan :200 OK

Ini akan masuk dengan benar melalui otentikasi cookie, dan mengembalikan hasil yang mirip dengan ini:

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

Saya telah membuat modul contrib bernama jDrupal yang membuatnya sangat mudah untuk masuk dengan JavaScript (antara lain):

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

Sebelum ke Drupal 8.2

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

Anda akan mengirim data di URL sebagai string kueri. Hasilnya akan berupa HTML, sehingga tidak akan mengembalikan apa pun yang berguna bagi Anda, tetapi itu akan masuk dengan benar melalui otentikasi cookie.


Jadi mengembalikan HTML tidak bisa dihindari?
niksmac

Pada titik ini AFAIK, ya HTML tidak bisa dihindari. Saya membayangkan ini akan ditingkatkan dari waktu ke waktu, karena misalnya belum ada cara untuk mendaftarkan pengguna melalui REST, tetapi masalah telah terjadi.
tyler.frankenstein

itu tidak berfungsi untuk saya, apakah diharuskan menggunakan Otentikasi Dasar juga?
Yusef

FYI, JSON dikembalikan pada Drupal 8.2, jadi tidak ada lagi HTML yang dikembalikan.
tyler.frankenstein

8
  1. Permintaan HTTP tidak tenang berdasarkan tipe konten.
  2. " REST Login " secara teknis adalah sebuah oxymoron.

Otentikasi ISTIRAHAT berarti mengirim autentikasi dengan setiap permintaan karena itu stateless. Contoh yang diberikan oleh inti Drupal 8 adalah modul Basic Auth, yang memungkinkan untuk mengirim kredensial otentikasi untuk permintaan HTTP melalui Basic HTTP Authentication yang diberikan kepada pengguna dengan izin untuk mengakses Konten melalui GET.

Contoh yang tenang

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

Namun ini biasanya tidak cukup baik. The simple_oauth dan oauth modul contrib memberikan OAuth 2 dan 1 dukungan masing-masing., Dengan yang permintaan HTTP dapat dibuat dengan otentikasi OAuth token didasarkan pada karya OAuth arus dijelaskan dalam modul tersebut.

Tapi pertanyaan sebenarnya sepertinya

Bagaimana cara saya masuk melalui API Layanan Web?

Tidak ada modul Drupal 8 yang stabil untuk melakukannya, tetapi modul Layanan menyediakan metode untuk membuat tindakan non-RESTful dan tindakan tertarget seperti "login".

Berikut ini berfungsi setelah menyiapkan titik akhir yang disebut "api":

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

Ini mengembalikan id dan nama sesi JSON (juga diatur dalam tajuk Set-Cookie respons).

dan juga Anda dapat masuk dengan panggilan ajax Jquery dengan cuplikan berikut

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

Layanan tampaknya keren, namun inti Drupal kacau di D8 IMO. ada banyak lagi yang akan datang.
niksmac

1
Sejak Drupal 8.2 Anda dapat (dan harus) menggunakan metode yang dijelaskan dalam drupal.stackexchange.com/a/221045/13237
andeersg

4

Versi Drupal Core: 8.x-4.x

Anda harus mengaktifkan layanan login pengguna hal pertama, ini dapat dilakukan dengan banyak cara, saya lebih suka menggunakan modul REST UI .

Pergi ke / admin / config / services / rest dan aktifkan sumber daya User Rest.

Setelah diaktifkan, Anda dapat pergi ke / admin / config / services / rest / resource / entitas% 3 Pengguna / edit dengan mengklik Edit di sebelah sumber daya Pengguna . Pastikan untuk mengaktifkan metode GET .

masukkan deskripsi gambar di sini

Sekarang Anda telah menyiapkan semuanya, Anda dapat mulai menggunakan layanan dengan menjalankan perintah ini di terminal atau dengan menggunakan aplikasi apa pun untuk permintaan curl seperti: Postman dan Restlet klien.

CATATAN : Token CSRF dapat diperoleh dari: / 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'

Objek yang dikembalikan adalah sebagai berikut:

SUKSES :

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

GAGAL :

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

> Pergi ke / admin / config / services / rest dan aktifkan sumber daya User Rest. Saya pikir Anda tidak perlu mengaktifkan sumber daya Pengguna untuk masuk dengan REST api. Mengaktifkan sumber daya ini hanya diperlukan jika Anda ingin melakukan operasi CRUD pada entitas Pengguna. Masuk dapat dicapai dengan api sisanya seperti yang disebutkan oleh @ tyler.frankenstein
MutantMahesh

2

Saya menggunakan login RESTFul khusus pada drupal 8 tetapi tidak dengan cookie. Ini untuk aplikasi seluler dan setiap kali saya membutuhkan informasi, saya menggunakan Otentikasi sederhana:

Karena Drupal 8.2x kita membutuhkan 2 file dalam modul:

rest.ressource.user.rest_ressource.yml di folder config / instal

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

Anda dapat menambahkan lebih banyak metode seperti DELETE / POST

Maka kita perlu file tersebut

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

        }

    }

Jangan lupa untuk langsung ke pengguna untuk menerima metode GET / POST atau apa pun yang Anda tambahkan dalam konfigurasi Anda.

Dengan itu Anda dapat membuat setiap file REST kustom untuk setiap entitas kustom.

Dan di js saya: Jangan lupa menelepon

yoursiteUrl / rest / session / token

untuk mendapatkan 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;

                          });

2

Mengikuti jawaban @ tyler.frankenstein, jika Anda ingin menerapkan formulir login dengan Ajax, Anda dapat menggunakan jQuery misalnya.

1. Dapatkan token CSRF

Kita perlu membuat permintaan POST ke user/logintitik akhir API Drupal 8. Titik akhir ini (dianggap sebagai "metode tidak aman") mengharuskan Anda mengirim token CSRF.

Langkah pertama adalah mendapatkan token ini dengan mengirimkan permintaan AJAX ke rest/session/tokentitik akhir:

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

NB:

  • The callbackparameter adalah fungsi callback yang akan dipanggil saat token CSRF akan diambil
  • Kami menggunakan Drupal.urlfungsi untuk mendapatkan URL dasar situs

Token ini harus dikirim dengan X-CSRF-Tokentajuk.

2. Login

Pertimbangkan HTML berikut:

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

... dan kode jQuery yang sesuai:

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

Kode ini telah berhasil diuji dengan Drupal 8.3.

Saya harap ini akan membantu Anda!


1

Ya tentu, saya membuat blog tentang cara mengujinya dengan tukang pos , dan juga satu lagi tentang cara mengkonfigurasi situs drupal Anda .

Dalam proyek ini saya membuat login untuk Drupal dengan sudut, menggunakan modul OAuth Sederhana untuk token.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.