Open HaroldRKnieriem opened 9 years ago
@HaroldRKnieriem please use GitHub Markdown when posting issues/comments. I've updated the issue to include some basic markdown to help wrap the json output.
As for the issue(s), from the output above, it looks like the login call correctly logs in, since user # 14 is coming back in the response data
.
It appears it is the subsequent connect
call (processed automatically after logging in) that is reporting the user as anonymous.
Are you developing your app in the same domain as the Website? i.e.
// drupal site lives here
www.example.com
// app lives here
www.example.com/mobile-application
@signalpoint Thank you for you quick response, and I apologize for the lack of Markdown. This is my first GitHub issue.
They are both on the same domain, currently:
// app lives at
http://lp-sales.home.dev/
// drupal lives at
http://lp-sales.home.dev/services
I also noticed that with both sites in the same browser (different tabs) that logging in via the app does correctly log me in on the Drupal site tab, so the process is working. I did find this article https://www.drupal.org/node/2342105, but it looks as though the connect function does have the CSRF-Token in the header.
@HaroldRKnieriem thank you for clarifying. Will you please share some sample code of your usage of drupal.user_login()
?
@signalpoint Here's the start of my app.js.
(function() {
var app = angular.module("salessheet", ['angular-drupal']);
app.run(['drupal', function (drupal) {
drupal.user_login('admin_hfa', 'Pass1234').then(function (data) {
if (data.user.uid) {
alert('Hello ' + data.user.name + '!');
drupal.node_load(1).then(function (node) {
alert(node.title);
});
}
else {
alert("failed login");
}
});
}]);
// The angular-drupal configuration settings for my simple app.
angular.module('angular-drupal').config(function($provide) {
$provide.value('drupalSettings', {
sitePath: 'http://lp-sales.home.dev/services',
endpoint: 'api'
});
});
...
@HaroldRKnieriem Just to confirm... and then the data.user.uid
always comes back as zero?
@signalpoint Yes. The connect function returns data.user.uid
as 0 and the data.user.rules
object comes back as 'anonymous user'.
@HaroldRKnieriem that is strange, I'm not sure why that is happening. What if you copy/paste the code that powers the user login
(so you can make your own manual call), and then in its then
callback make a to system connect
with your own manual call. What happens then? I'm curious if even without angular-drupal
, if it will work or not in your environment.
@signalpoint I've run into the same issue as well.
@cgranville will you please describe your development environment? i.e. localhost vs remote, application (web, mobile) vs headlesss, any cross domain issues, CORS policy.
For me personally, I've used it with the environment described here: http://tylerfrankenstein.com/code/headless-drupal-angular-js-bootstrap
In order to properly resolve this, we should learn as much as we can about the different environments, and how we can have this module operate properly.
@signalpoint Environment: Angular appLocalhost:2000, Drupal: localhost: 8083 Allow-Origin: * Allow-Headers: Origin, Content-Type, Accept, X-CSRF-Token, Authorization, Token Allow-Methods: PUT, GET, POST, DELETE, OPTIONS
@cgranville I suppose the *
should allow the communication between 2000 and 8083, but that's a realm of skills I'll defer to your judgement on. Have you tried launching e.g. Chrome with security disabled?
On a side note, I am still a n00b
with Angular, but I recall there being a way to launch an app via the terminal (i.e. not just navigating to a URL in the browser). It's possible that while launching an app in the aforementioned way, results in cookies not being set properly in the app's browser, and may result in this anonymous behavior.
After a bit more research, it appears running the app and Drupal on the same port is a good idea if you want to avoid potential CORS issues. This way the cookie should be set properly, and the authentication should hold across page visits.
I'm using this on a subdomain (using http-server & proxypass in the apache config) and initially got the same login issue - the session is created but the browser wouldn't store/use the cookie when making subsequent requests & returned an anonymous user error.
I was able to get round this by adding the 'withCredentials' header to all requests:
angular.module("angular-drupal").config(['$httpProvider',
function($httpProvider) {
$httpProvider.interceptors.push(['$q',
function($q) {
return {
request: function(config) {
config.withCredentials = true;
return config;
}
};
}
]);
}
]);
and also setting "Access-Control-Allow-Credentials" "true" in the apache config.
@openbook Thank you for the detailed explanation of the way around the issue, much appreciated!
I think you should use the token got from user/login post, don't make a session/token get after it, because if you don't have the cookie set, that will return a new, anonymous session token. Plus one spare http request less.
@thomas7373 thank you for pointing this out. It wasn't always this way, Services used to not include the token in the result of the user login call. I'll create a separate issue for this to have the extra call removed from the login success.
@openbook Thank you very much , I spent hours trying to resolve annonymus user login and your fix solved my problem
I ended up adding this to my a drupal module that also has additional services. Might not be 100% (Not sure I like the use of current_path();) but seems to allow me to configure origins that can connect to my services with an angular app. I have a admin page that I can configure origins. Since you can only have 1 origin at a time I'm doing a check to make sure the server origin is from one that I set.
function mymodule_init() {
$paths = explode('/', current_path());
if ($paths[0] == 'api' || $paths[0] == 'services') {
$origin = $_SERVER['HTTP_ORIGIN'];
$origins = explode(',', preg_replace('/\s+/', '', variable_get('mymodule_allowed_origins', '')));
if (in_array($origin, $origins)) {
drupal_add_http_header('Access-Control-Allow-Origin', $origin);
drupal_add_http_header('Access-Control-Allow-Credentials', 'true');
drupal_add_http_header('Access-Control-Allow-Headers', 'Content-Type, X-CSRF-Token');
}
}
}
@openbook , @signalpoint I'm developing a mobile app using the seed https://github.com/mario-aleo/cordova-angular-angularMaterial-seed. To interact with Drupal services I'm using https://github.com/easystreet3/angular-drupal.
cordova serve
I'm running my cordova app in localhost
.The issue is, when I login Drupal returns the user as anonymous. As you said I tried withCredentials
but still I'm getting the uid as zero.
In the cosole
we can see like, when submit to user/login.json
, it successfully logged in and can see a token
. then it calls the URL service/session/token
which returns a different token. then it calls system/connect.json
which shows the uid=0 (anonymous user)
app.js
/**
* @file
* Main app.
*/
"use strict";
/*jslint browser: true, unparam: true */
var myApp = angular.module("ngapp", [ "ui.router", "ngMaterial", "ngCookies", "ngMessages", "ngCordova", "ngStorage", "revolunet.stepper", "angular-drupal" ])
// The ngTouch is No Longer Supported by Angular-Material.
.run(['$rootScope', '$cordovaDevice', '$cordovaStatusbar', '$log', '$http', '$location', '$localStorage', function ($rootScope, $cordovaDevice, $cordovaStatusbar, $log, $http, $location, $localStorage) {
$log.debug("App running...");
// Status bar related.
document.addEventListener("deviceready", function () {
// Always Show Status Bar.
$cordovaStatusbar.overlaysWebView(false);
// Status Bar With Green Color, Using Angular-Material Style.
$cordovaStatusbar.styleHex('#2A771B');
if (window.plugins && window.plugins.orientationLock) {
window.plugins.orientationLock.lock("portrait");
}
}, false);
/* Hijack Android Back Button (You Can Set Different Functions for Each View by Checking the $state.current)
document.addEventListener("backbutton", function (e) {
if($state.is('init')){
navigator.app.exitApp();
} else{
e.preventDefault();
}
}, false);*/
}])
// Angular-Material Color Theming.
.config(function ($mdThemingProvider, $mdGestureProvider) {
$mdGestureProvider.skipClickHijack();
$mdThemingProvider.theme('default')
.primaryPalette('green')
.accentPalette('light-green');
})
// Angular Drupal Configuration Settings.
.config(['$provide', function ($provide) {
$provide.value('drupalSettings', {
sitePath: 'http://demo.drupal.backend/',
endpoint: 'api/v1'
});
}])
// CORS issue fix.
.config(['$httpProvider', function ($httpProvider) {
$httpProvider.interceptors.push(['$q',
function ($q) {
return {
request: function (config) {
config.withCredentials = true;
return config;
}
};
}
]);
}]);
LoginController
"use strict";
/*global kiranaApp */
/*jslint unparam: true, white:true, devel: true */
myApp.controller('LoginController', ['$scope', '$location', 'drupal', function($scope, $location, drupal) {
var vm = this;
function test_login () {
drupal.user_login("Admin", "Admin@123").then(function(data) {
console.log(data);
alert('Hello world and hello ' + data.user.name + '!');
});
}
vm.login = function() {
test_login();
};
}]);
I'm testing the app in Chrome/Firefox by disable the disable-web-security
and enable CORS
plugins. I don't know these kind of setting will affect when I build the .apk. :-)
Do you have any thoughts about why the user is logged in as anonymous? Is there any other settings I'm missing in Drupal/AngularJS side?
When I try to login to the Drupal site the login is failing. Any help would be appreciated.
FYI: I added console.log statements in the user_login and connect functions. Here is the output:
_userlogin():
connect():
Drupal Module: Services: 7.x-3.12