用户登录REST格式


13

有人在Drupal 8上有有效的 REST登录吗?

这就是我尝试过的。

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

Answers:


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您正在使用什么来测试呼叫?我用邮差,因为它让我的浏览器Cookies和说我是在登录之前有过这样的问题,你可以通过在浏览器中退出并重新发送请求进行测试。
安特罗·杜阿尔特

11

以下是通过JavaScript登录Drupal 8 REST的方法:

Drupal 8.2及更高版本

  • POSThttp://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"
}

我创建了一个名为jDrupal的contrib模块,该模块可以非常容易地使用JavaScript登录(以及其他功能):

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

在Drupal 8.2之前

  • POSThttp://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 '16

在这一点上AFAIK是的,HTML是不可避免的。我以为这会随着时间的推移而得到改善,因为例如还没有一种通过REST注册用户的方法,但是出现了问题。
tyler.frankenstein 2016年

它对我不起作用,是否也需要使用基本身份验证?
Yusef

仅供参考,从Drupal 8.2起返回JSON,因此不再返回HTML。
tyler.frankenstein 2016年

8
  1. HTTP请求不是基于Content-Type的RESTful。
  2. 从技术上讲,“ REST登录 ”是矛盾的。

RESTful身份验证意味着随每个请求发送身份验证,因为它是无状态的。Drupal 8内核提供的示例是基本身份验证模块,该模块允许通过基本HTTP身份验证发送HTTP请求的身份验证凭据,前提是用户有权通过GET访问Content。

RESTful示例

卷曲: 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服务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会话ID和名称(也可以在响应的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核心在D8 IMO中混乱了。还有很多。
niksmac '16

1
从Drupal 8.2开始,您可以(并且应该)使用drupal.stackexchange.com/a/221045/13237
andeersg

4

Drupal Core版本:8.x-4.x

您首先需要启用用户登录服务,这可以通过很多方式实现,我更喜欢使用REST UI模块。

转到/ admin / config / services / rest并启用“ 用户休息”资源。

一旦启用它,你可以去/管理/配置/服务/ REST /资源/实体%3Auser /编辑通过单击编辑旁边的用户资源。确保启用GET方法。

在此处输入图片说明

现在,您已完成所有设置,可以通过在终端中运行此命令或通过对任何卷曲请求使用任何应用程序(例如PostmanRestlet客户端)来开始使用该服务。

注意: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操作时,才需要启用此资源。可以使用@ tyler.frankenstein提到的rest api来登录
MutantMahesh

2

我在drupal 8上使用自定义RESTFul登录,但不与cookie一起使用。它用于移动应用程序,每次我需要信息时,我都使用一个简单的Authenticate:

从Drupal 8.2x开始,我们在一个模块中需要2个文件:

config / install文件夹中的rest.ressource.user.rest_ressource.yml

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

那我们需要文件

src / Plugin / rest / resource中的userRestRessource.php

    <?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 / rest / session / 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

按照@ tyler.frankenstein的答案,如果您希望使用Ajax实现登录表单,则可以使用jQuery。

1.获取CSRF令牌

我们需要向user/loginDrupal 8 API 的端点发出POST请求。该端点(被视为“非安全方法”)要求您发送CSRF令牌。

第一步是通过向rest/session/token端点发送AJAX请求来获取此令牌:

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

注意:

  • callback参数是一个回调函数,将在获取CSRF令牌时调用该函数
  • 我们使用该Drupal.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网站的博客。

在这个项目中,我使用了简单的OAuth模块作为令牌,使用angular登录了Drupal。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.