Posted by pmunch on March 16, 2015 at 12:46am
Hi all,
I have spent hours trying to figure this out as well as finding relevant code examples, I'm stuck...
I'm building a basic phonegap app that should allow to post a node as authenticated user. I can successfully login, but I cannot further post as this authenticated user thru X-CSRF-Token: I always get 403 - "Access denied for user 001" ...
I summed up the steps I follow in the dummy loginAndPost() function below.
function loginAndPost() { // Set some vars var username = "001"; var password = "001"; var server_uri = "http://my-drupal-website"; var services_endpoint = "00"; // Step 1 : Get a session token from /services/session/token var xhr_1 = new XMLHttpRequest(); var xhr_1_url = server_uri+"/services/session/token"; xhr_1.open('GET', xhr_1_url, false); xhr_1.send(); var xhr_1_token = xhr_1.response; console.log(xhr_1_token); // Step 2 : Login using credentials AND session token var xhr_2 = new XMLHttpRequest(); var xhr_2_url = server_uri + "/" + services_endpoint + "/user/login.json"; xhr_2.open('POST', xhr_2_url, false); xhr_2.setRequestHeader("Content-type", "application/json"); xhr_2.setRequestHeader('X-CSRF-Token', xhr_1_token); xhr_2.data = { "username":username, "password":password, }; xhr_2.send(JSON.stringify(xhr_2.data)); var xhr_2_resp = JSON.parse(xhr_2.response); console.log(xhr_2_resp); // Setp 3 : Create an article node as authenticated user var xhr_3 = new XMLHttpRequest(); var xhr_3_url = server_uri + "/" + services_endpoint + "/node.json"; xhr_3.open('POST', xhr_3_url, false); xhr_3.setRequestHeader("Content-type", "application/json"); xhr_3.setRequestHeader('X-CSRF-Token', xhr_2_resp.token); xhr_3.data = { "title":"my_title", "type":"article", "body":{ "und":[{ "value":"This is the body" }] }, } xhr_3.send(JSON.stringify(xhr_3.data)); var xhr_3_resp = JSON.parse(xhr_3.response); console.log(xhr_3_resp); }
I'm using drupal 7.22, and services 7.x-3.11.
Any hint someone ?
Many thanks in advance...
Comments
New Token Needed After
After logging in, you need to get a new CSRF Token to pass along. The token you receive as an anonymous user, will be different than the token used for the same user authenticated.
On a side note, jDrupal and/or DrupalGap will be very helpful here. With jDrupal you can just do:
jDrupal takes care of all the token retrieval and other heavy lifting. Then you can use DrupalGap to quickly build mobile/web apps for Drupal (built on top of PhoneGap/Cordova)
Same pb using jDrupal
Hi Tyler,
Thanks for your reply.
I knew and have looked to jDrupal and Phonegap, which are both... amazing.
I intend to use phonegap in a next project.
Many thanks for sharing this.
So I tried to achive my authenticated node posting with jDrupal using the code you provided, and I still have the same pb...
I surely have something wrong in my code or environment:
1 / On my drupal (7.22) site:
I have the 2 basic node types :
- Article, with "create article" permission set to anonymous users
- Page, with "create page" permission set to authenticated users
"Access content" permission is set to anonymous users
Test user : username "001" has password "001"
I have the services 7.x-3.11 module activated, and 1 only service called "00":
- Machine-readable name of the endpoint: 00
- Server: REST
- Path to endpoint: 00
- Debug mode enabled: checked
- Session authentication: checked
- Response formatters: json
- Request parsing: application/json, application/x-www-form-urlencoded, multipart/form-data
- Resources: all checked
2 / My PhoneGap App
Basically consists in index.html and test.js
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no" />
<!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
<!-- Include meta tag to ensure proper rendering and touch zooming -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
<link rel="stylesheet" type="text/css" href="css/index.css" />
<script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<script type="text/javascript" src="js/jdrupal-7.x-1.1.min.js"></script>
<script type="text/javascript" src="js/test.js"></script>
<script type="text/javascript">
// Set the site path (without the trailing slash).
Drupal.settings.site_path = "http://my_drupal_website";
// Set the Service Resource endpoint path.
Drupal.settings.endpoint = "00";
</script>
</head>
<body>
<div data-role="page" id="page_home">
<div data-role="header"><h1>TEST jDRUPAL</h1></div>
<div data-role="main" class="ui-content">
<button onclick="createNode('article');">Create ARTICLE</button>
<button onclick="createNode('page');">Create PAGE</button>
</div>
<div data-role="footer" class="app-footer"></div>
</div>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript"> app.initialize(); </script>
</body>
</html>
test.js
function createNode(nodeType) {
var username = "001";
var password = "001";
user_login(username, password, {
success: function(result) {
console.log("User "+username+" logged in");
var node = {
type: nodeType,
title: 'hello',
body: {
und: [ { value: 'world' }]
}
};
node_save(node, {
success: function(result_2) {
console.log(nodeType+" node created");
},
error: function(result_2) {
console.log(nodeType+" node NOT created");
},
});
}
});
}
The results
Each posting makes successful authentication (drupal dblog says "Session opened for 001")
But:
- Article nodes are posted as anonymous users
- Page nodes posting results in "Access denied for anonymous users"
NB: I use PhoneGap Developer App for mobile testing on iOs and Android
Any idea ?
Many thanks in advance ;)