Piwik 1.5.1 Wrong number of visits and (unique) visitors - matomo

i just updated my piwik from 1.1.1 to 1.5.1 and having problems with the numbers of vists and visitors.
Each time i send a tracking request (with firefox 5) piwik increases the number of pages, vistis and visitors. That will be ok for my first request, but all of my following requests should only increase the number of pages, not visits or visitors.
Same request in IE9 increases the pages and visits. The number of visitors looks fine and increases only for the first request.
The old version did'nt have this behaviour.
I'm using the async tracking and this is what's defined in my pages:
var piwikSiteId = '2';
var _paq = _paq || [];
(function(){
var u="https://piwik.mydomain.net/piwik/";
_paq.push(['setSiteId', '2']);
_paq.push(['setTrackerUrl', u+'piwik.php']);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
var d=document,
g=d.createElement('script'),
s=d.getElementsByTagName('script')[0];
g.type='text/javascript';
g.defer=true;
g.async=true;
g.src=u+'piwik.js';
s.parentNode.insertBefore(g,s);
})();
I also tried the standard integration which was generated by piwik - the behaviour is the same as described above.
Piwik is installed under a subdomain like piwik.mydomain.net and the site is available under website.mydomain.net. It looks like a cookie problem for me but i'm not sure.
Maybe someone can help - where do i have to look solving this issue?
Thanks,
JJ

This was a bug in piwik and is now resolved.
Piwik changeset 5086

Related

AngularJs + Django RESTful: session based authentication

I'm developing an angular web application that will replace the current website that we have. The current website uses session based authentication. At the moment, I can't access the hosted API with get or post requests.
I'm developing the angular application on my local computer using a python simple server, whereas the api is hosted online.
I would prefer to find a fix that's completely in angular since I can't change the API without help (it was written by my boss a while ago, and is now used in the production version). I don't have a login page so I'm just trying to provide the authentication information in my headers and requests.
My angular application was written independent of django. I just want to access the django backend
So far I'm trying the following to set the headers:
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
$httpProvider.defaults.headers.common = {'username': btoa('myUsername'), 'password': btoa('myPassword')
};
}]);
And in my service:
app.factory('Test', ['$resource', function($resource) {
return $resource('https://www.phonywebsite.org/en/api/test/')
};
I consistently get 301, 400 and 403 errors. Lately it's been mostly 301 errors and I get no response from the api. I'm using the Allow CORS chrome extension as a temporary fix to try to get to the api without getting a CORS policy error.
My questions
How can I fix the CORS errors without using the chrome extension?
How do I provide my authentication to my django backend that uses session based authentication making sure the csrf cookie its looking for is in the header?
To answer your first question, using the cors extension is a temporary solution and should mostly never be used cause your clients might not use it. To handle CORS, you need to understand how cross site API calls work. In short CORS is a mechanism that allows AJAX requests to circumvent their same origin limits. To handle such situations you need to update your backend and add
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
. Once you add this your settings.py should stop getting CORS issues.
To answer your second question, angular already provides you with support for CSRF so half of your battle is already won. What you need to do is add a patch on your module to start accepting csrf tokens (The name is a bit different in angular). You have already done this and done a good job of it as well:
var app = angular.module('app', ['...']);
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
}]);
What this would do is make sure that whenever you make a $http call your csrf token is set as well.
As a learning oppurtunity, you could also try using ng-cookies as well. To go further to explain this, whenever you make a call in angular , your request in bundled with cookies as well so you can easily access them in request.COOKIES.
You need to change how you are calling your API as well, something like:
app.factory('APIService', function ($http) {
return $http({url: 'https://www.phonywebsite.org/en/api/test/',
method: 'GET'})
}
You can obviously make modifications to this but I think this shows the $http usage to make you understand the general gist.
You can try to add some more authentication around your application here as well (or replace django auth with your own custom auth), but that is on your use case.
Hope this helps.

Ionic on iOS not sending request to external Api

I have custom api written in WebApi2 that serves some data in json. I'm trying to access that particular API from Ionic on iOS and Android using Angular's $http. On Android everything is ok and I'm receiving correct result. But on iOS strange thing happens, as $http even don't send request and throws error immidiately, returning http status code 0. This problem exists only on iOS emulator and iPhone. Moreover, this behavior is not observable when requesting any other site or fake test api.
What I already tried:
Add "Access-Control-Allow-Origin: *" header.
Add proxy to ionic.project, but this fixed the problem only when running Ionic Serve
Add in config.xml
configure angular to use cross-domain by setting this:
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
Any clues? Maybe this is server-side problem?
Does this also happen on an iOS version lower than 9.0? Because there has been some problems with $http since iOS 9.0. If it doesn't, it would check out this article.
Looking for solutions
When I started searching for this error I found this forum thread. It
said that the contributors had got this error too and that the error
is triggered when a network request is made using the $http service. I
used $http in my app too, but I didn’t make any request through it
when the app was starting. Also, in the forum thread it said that the
problem is triggered by adding custom headers to a network request. To
solve the problem, headers shouldn’t have a leading space in the
value. I had custom headers but I didn't have any spaces before the
value. So I decided, (wrongly as it turned out), that this article
couldn't help me.
Here’s what I tried next:
I read all the advice from Ionic's blog article again and tried to
apply it to my project - it didn’t help. I decided that as I was
getting the error in vendor files, I should try updating Ionic
Framework, Ionic CLI and all third party libraries (Angular,
Restangular, ngStorage, ...) - it took some time, but when I ran the
app again I got the same error. I created a new "clear" ionic app and
it worked properly - so I was sure that the problem was somewhere in
my code. I started debugging the app and digging around in my code in
"the old school way" - trying to cut out blocks of code and see if the
app would then work (because I got the error before it was possible to
use any Safari dev tools for debugging). In this way I found out which
line in my code was triggering this error. It was this line:
$http.defaults.headers.common.Authorization = 'Basic ' + $localStorage.user.authToken;
I use my own service in dependency
injection which executes a line of code (see above) when the service
is initialized. This is why the $http service was also causing the
error I was encountering. I removed this line from my code and
replaced it with authorization token headers in the configuration of
each request, like this:
$http.post(appConfig.apiUrl + 'profile', data, { headers: {'Authorization': $localStorage.user.authToken} })
After that my app started to load (Hurrah) which let me see some other
problems (Booo).

How do I connect to a Cloudant database through pure angularJS

I've been using JSON strings to store my data and was thinking of moving to Cloudant. I've been searching long and hard for a tutorial or example code of this but one doesn't seem to exist (there are one with Node + Angular which uses the RESTAPI, but I'm a beginner in NodeJS and can't see a way to attach it to AngularJS)
I currently use this code to connect to my local.json file
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$http.get("data.json")
.success(function(response) {$scope.experience = response.experience;});
}
Can someone help me connect to a Cloudant database?
Based on your question found below links:
https://cloudant.com/blog/chaise-blog-building-a-diary-with-angular-js-grunt-js-and-cloudant/#.VjuuD6QT2ko this article has an example code on how to connect to cloudant by:
$http({
url: [root, post._id].join('/')
, method: 'PUT'
, data: post
})
.success(function(data, status){
post._rev = data.rev;
$timeout(_autosave, 5000);
})
Accessing the DB in Cloudant with Angular refers to a cloudant article which you can apply to angularjs https://cloudant.com/for-developers/crud/#browser-update
A few things you can try:
API Keys
https://docs.cloudant.com/authorization.html
After you've read up on Cloudant API Keys, try prepending your calls with one, like this:
https://<YOUR API KEY>:<YOUR API KEY PASSWORD>#<YOUR CLOUDANT USERNAME>.cloudant.com/<YOUR DATABASE NAME>
This will, obviously, not be good for the long term, b/c you'll have your creds in your client-side code, which anyone who views your Javascript can see.
You'll probably want to dig back into Node, to avoid this. Check out Cloudant's supported library for Node: https://github.com/cloudant/nodejs-cloudant
Enable CORS in Cloudant
https://docs.cloudant.com/cors.html
This will allow your client-side code running on, say, 127.0.0.1, to make Cloudant requests. (Make sure that everyone has _reader privileges.)
There are plenty of other things you can do, too, like creating proxies, but this should get you going.
I've figured it out, finally. No idea how or why there is no clear documentation on what header values are needed at the start, figured I'd share what I found:
You first have to enable CORS settings through the cloudant website-- (Users > Cors > Enable cors) and then set withCredentials to true in your http request.
The full code to connect is available here:
https://github.com/gweennnnn/cloudantangularconnect

AngjularJs current user solution

I am new to AngularJs. My question is how to store current user data after user logged in?
I have come across lots of solutions recommending the use of service, and inject the service into controllers. Something like this:
customer.factory('service', function(){
var auth = {};
auth.currentUser = null;
auth.setCurrentUser = function(data){
auth.currentUser = data;
};
return auth;
})
This worked perfectly for me until I hit the refresh button of the browser, all information stored in Javascript variable are lost.
To solve this problem, do I have to use $cookieStore or something similar? I have seen few people mentioning ui-route, I can't quite get my head around it. Is ui-route relevant to this discussion? Also I would like to use the same solution to save authentication token for the logged in user.
What is your general opinion around this issue? Thank you so much in advance.
Ui-route
I think you mean AngularUI Router which is a routing framework for AngularJS. It has got nothing to do with persistent storage.
Services
Angular Services are singletons. It is used to organize and share code across your app. It is instantiated when a component such as a controller needs it. Once you close your app or reload it, the data in it is lost and it is re-instantiated when needed.
Then how to persist data?
Using $cookies
Get angular-cookies.js
Include the dependency in your app angular.module('app', ['ngCookies']);
Include $cookies dependency in you controller or service (where you want to access the cookies)
//Getting a cookie
var favoriteCookie = $cookies.get('myFavorite');
// Setting a cookie
$cookies.put('myFavorite', 'oatmeal');`
See documentation.
Using HTML5 Local Storage
"With local storage, web applications can store data locally within the user's browser.
Before HTML5, application data had to be stored in cookies, included in every server request. Local storage is more secure, and large amounts of data can be stored locally, without affecting website performance.
Unlike cookies, the storage limit is far larger (at least 5MB) and information is never transferred to the server.
Local storage is per domain. All pages, from one domain, can store and access the same data." - via W3Schools
While you can use pure JS for local storage, ngStore is a library that you can use with AngularJS. It provides you with localStorage and sessionStorage .
$localStorage - stores data with no expiration date
$sessionStorage - stores data for one session (data is lost when the tab is closed)
Dependency for your app:
angular.module('app', ['ngStorage']);
Then
$localStorage.visitorCount = 500;

Google App Engine Channel API javascript location

I'm a bit confused about this, and want to make sure I'm not being naive about how this works. Does the client side javascript have to also be hosted on Google App Engine? Say I create a channel on my dev server, then I have a local HTML file (non-hosted) on my computer with the required javascript, and I connect to that channel with a token - will that work? Or is this not how channels work?
Edit:
All I have is an HTML file in the same directory as my app.yaml file (so the root directory for my website). I'm in the devserver.
First I create a channel and get the token:
token = channel.create_channel('1')
print token
>>> channel-4132644671-1352248413-1
Then I copy that token in my HTML file:
<html>
<head>
<script type="text/javascript" src="http://localhost:8080/_ah/channel/jsapi"></script>
</head>
<body >
<script>
var token = 'channel-4132644671-1352248413-1';
var channel = new goog.appengine.Channel(token);
var socket = channel.open();
socket.onopen = function() { alert('open'); };
socket.onmessage = function() { alert('message'); };
socket.onerror = function() { alert('error'); };
socket.onclose = function() { alert('close'); };
</script>
</body>
</html>
I open the HTML file with Safari. I get an alert saying "open". However, no matter what token I type in var token, I get an "open" alert, so I'm not sure if getting that alert means anything.
Then I do:
channel.send_message('1', 'hi')
And nothing happens in my HTML file. No alerts. What am I doing wrong?
Because of the same origin policy, the script must be hosted on the same domain as the server that the app opens the channel to. With the present implementation, that server is talkgadget.google.com and the supporting script is https://talkgadget.google.com/talkgadget/channel.js. With curl you can see that the /_ah/channel/jsapi endpoint of your app simply issues a 302 redirect to that script. So unless you intend to develop and run your own channel server, no, you can't do this.
Furthermore, if the underlying implementation of channels should happen to change in the future, App Engine would be updated to redirect /_ah/channel/jsapi to a new script so existing apps would continue to work, while a custom approach would likely break. One less reason to do it yourself.
In the dev_appserver, the channel is implemented by a javascript function that's constantly polling the server.
If your dev_appserver isn't actually running (it looks like you've somehow broken into dev_appserver), the polling function isn't going to succeed and you won't get the channel messages.
On production, it looks like the channel API uses some sort of long polling.
Also, I'd have to double check the docs, but I believe the first param to send_message should be the token.

Resources