7

I have a site where a custom form is in opened in a modal, and when submitted calls an ajax function to POST to a REST service to create a node.

The problem is I keep getting "Forbidden" response upon submission.

I only want logged in users to be able to send these ajax requests and the auth should be different token for each user.

Here is my code:

$('#create-node-submit').click(function(e) {
    e.preventDefault();
    var newNode = {
        _links: {
            type: {
                href: 'http://mysite.dev/rest/type/node/article'
            }
        },
        type: {
            target_id: 'article'
        },
        title: {
            value: 'This is a test Article from REST'
        },
        field_description: {
            value: 'Here is some test description.'
        }
    };
    getCsrfToken(function (csrfToken) {
        postNode(csrfToken, newNode);
    });

    return false;
});

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

function postNode(csrfToken, node) {
    $.ajax({
        url: 'http://mysite.devdev/entity/node?_format=hal_json',
        method: 'POST',
        headers: {
            'Content-Type': 'application/hal+json',
            'X-CSRF-Token': csrfToken
        },
        data: JSON.stringify(node),
        success: function (node) {
            console.log(node);
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            console.log("Status: " + textStatus);
            console.log("Error: " + errorThrown);
        }
    });
}

When running a test in POSTMAN it is successful, but the authentication was slightly different there: enter image description here

As you can see in the picture, I get 201 created when using POSTMAN.

I believe it has to do with the CSRF token being used in the Javascript implementation. I'm not sure what authentication method I'm supposed to use when POSTing to the same site via JS.

I used the information here.

I created a bug report as it seems the CSRF token check passes successfully and grants access, but access is denied from somewhere else. Issue #2831251 Trying to create nodes via REST with ajax POST request returns 403 response

2

You can use Postman, a Google Chrome browser app that allows you to POST, GET, PATCH, and DELETE to any site (for testing purposes), to generate the code for you:

enter image description here

After completing the 3 steps shown in the picture, you need to perform 1 more step:

  1. Then paste the code into your custom module.

PS: I believe you can delete the postman-token line in the headers.

| improve this answer | |
  • That's great and all, but I don't want everyone to have access to that "Basic" token auth, which was generated by the admin credentials. It should be generated for each user and not at all for anonymous users. – CR47 Nov 23 '16 at 16:37
  • @CR47 I do not think, you can extract data for basic auth when already logged in. It seems, that you will need to use other autentification method, such as cookie authentification or your own custom authentification – Juraj Nemec Nov 25 '16 at 21:41
  • @JurajNemec The cookie is sent by default with ajax request. I also narrowed down the issue to what is probably a bug in core. The CSRF token check actually passes, and there is a fail happening somewhere else in the chain which I have been unable to find so far. I updated the question with a link to the bug report on drupal.org. – CR47 Nov 28 '16 at 20:14
  • Never heard about this postman, does hè "always ring twice" (as in the movie)? Would you mind adding some details about it to explain/introduce it a bit? PS: I do not understand the"4." in your answer ... – Pierre.Vriens Nov 29 '16 at 7:13
  • 1
    My mentioning of POSTMAN request succeeding was more of a test to see if the endpoint actually worked. The issue is the authentication as described in the question. Sending the hashed admin username/password in every request for all users is not an option in this case, so this answer does not really help solve the problem at hand. I added a link to the issue on drupal.org to the question which helps explain more. – CR47 Nov 29 '16 at 16:52
2

The issue was due to a bug in Rest UI module v.1.13 for D8.

As of writing this, the issue is not resolved on the module, but there is a workaround.

To get around the problem, configs exported from Rest UI need to be adjusted under "authentication".

See here for more info: https://www.drupal.org/node/2831716#comment-11813802

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.