Google App Engine short URL tracking with Google Analytics - google-app-engine

My website generates some short URLs when users share a link (ex: http://futureo.us/l/ixjF).
These short URLs redirect the user to the original content I'm linking to. Before redirecting, the app renders a page that contains only Google Analytics javascript code.
Currently my handler code looks like this:
class PostHandler(handler.Handler):
def get(self, code):
#strip URL shortcode
code = code.strip('/')
#grab URL based on shortcode
url = scripts.urlshort.getURL(code)
if url:
self.render('tracking.html')
self.redirect(str(url))
else:
self.write('Code not FOUND.')
This solution isn't working. GA is not registering pageviews to these short links. I would alo like to see who where the referrers to these short-links.
Any ideas how I could fix this?

I believe your problem is that you're adding an HTML tracking code, in a response that has HTTP redirection. Probably the HTTP redirection is processed earlier than the HTML, if the latter is evaluated at all.
Seems to me that the best solution would be to track the redirects on the server side rather than on the client side. As these are redirects anyway, you don't need to track client-only data such as time spent on page, page events etc. Tracking the redirect would be most accurate and simpler if done in the python code. (I don't know, though, of a way to use the google analytics tools for tracking these; for my uses I just track the redirects in an NDB model).
Another solution, which might be slower on the user experience, is to avoid using HTTP redirect (self.redirect) and instead put a javascript client-side redirect which will be evaluated after the tracking code.
window.location = "{{url}}";

Related

Server redirect to login url from AngularJs page containing # (hash) sign

I use Spring Security to deal with session timeout. My application also uses AngularJs.
I have the following issue:
If the session times out and a user issues a non-ajax request from an angularJs page to a secured url, Spring Security redirects me to the login url but keeps the part of the Url after the # (hash) sign.
Let me illustrate:
A user is located at /myapp/foo#!/bar
Session times out
User issues get request to secured url
User is redirected to /myapp/signin#!/bar
How can I avoid the #!/bar part from being added to signin page?
Edit: There is a slight mistake in the description above. The problematic use case is as follows:
A user is not logged in and tries and access a protected resource such as: localhost:8080/bignibou/curriculum/#/view/1 (by pasting this url in browser's address bar for instance).
They will automatically be redirected to the following Url: http://localhost:8080/bignibou/signin#/view/1
Notice the part including and after the hash sign is kept. Note that this has more to do with AngularJs than Spring Security as Spring Security does not include the hash sign (this is confirmed by the fact that the hash never appears in the network tab of chrome dev tools...)
Rather than Angular, this sounds like the intended behavior for hash fragments on HTTP/3xx redirects, as implemented by most modern browsers (and IE9 onwards, I believe). There is a detailed explanation on the nuances here:
URL Fragments and Redirects
and the official documentation is here:
W3C URI handling - Section 4.1.
Edit:
In order to modify (or, in this case, remove) the fragment, you can leverage HTML5's history state. Try adding this to your signin page:
history.replaceState("", document.title, window.location.pathname + window.location.search)
For further information on the replaceState, it's pretty well documented at Adding and modifying history entries in the Mozilla developer docs.
The obvious caveat here, is what versions of IE you need it to work in. From a quick google, it seems like you are looking at IE10 onwards, so for earlier versions, you would therefore need something more rudimentary like:
window.location.hash = ""
which will remove the fragment but retain the #, but hey, it's IE.
As a composite solution, therefore, you could use:
if("replaceState" in history)
// proper browsers
history.replaceState("", document.title, window.location.pathname + window.location.search)
else
// fallback for ie
window.location.hash = ""
As Rob mentioned above, the hash is not being sent back by the server, it is simply being preserved by the browser.
You could however set your login and session expired URLs to `/login#' so that the server returns a hash in the redirect URL, thereby overriding any existing hash.

Can I change the welcome page depending on URL?

I have a single GAE app, which serves two different variations of the application depending on the invoked URL. Is it possible to have a per-url welcome page, without having the request map to a servlet which would slow the page load too much.
So, by way of example...
My app lives at myapp.appspot.com
I have two domains mapped to this app, myapp1.com and myapp2.com
If the user accesses myapp1.com, I want to serve myapp1-index.html, and
if he accesses myapp2.com, I want to serve myapp2-index.html
I never played with GAE on Java but I'm guessing you could do something based on the requested URL. I believe you can check the requested URL with the following inside your request:
httpServletRequest.getRequestURI()
Where httpServletRequest is the HttpServletRequest parameter from your doGet() method.

Backbone swtich from Http to Https

I have certain knowledge using Bakcbone.js, and my backend is Restlet Java, but have no idea regarding user authentication
I have built a single-page web app using them, but now the problem arises that, what I am going to do after user login? There are pages that can be viewed by both logged in and not logged in user, and logged in users should be able to see additional content.
By default the page uses http, but after user Login, suppose an Ajax Post, how do I switch entire Backbone App from http to https? And suppose user logs out, how do I switch back?
Are there any convient ways just to switch all my routes in Router, Url/Urlroots in Collection/Model between Http and Https? (using relative address)
Can I deal with this using Server Redirect..and how can I do that, doesn't that make Http and Https sections completely separated like two apps?
woha - that's a lot stuff you are thinking ..half of which doesn't even belong to Backbone's scope.
Let's split this up:
but have no idea regarding user authentication
read this. I just answered this yesterday.
what I am going to do after user login?
the normal pattern here is that login is usually one page. If the user successfully logs in then she is redirected to another page which has all the Backbone stuff in it e.g. take a look at a backbone app classdojo.com . Login is simple HTML with no fancy stuff. Once user logs in, she navigates to a single-page app with all heavy client side.
Are there any convient ways just to switch all my routes in Router, Url/Urlroots in Collection/Model between Http and Https? (using relative address)
Backbone Router ONLY looks at the route which comes '#' e.g. in example.com/user#details Backbone router will only navigate based on #details . It has nothing to do with your http protocol.
Your Url/Urlroots can be relative or absolute both. So you can specify full URL with http protocol in them.

HTML 301 Redirect in Google App Engine

I have 4 URLs that I would like to redirect to my main page. They are all just common misspellings and I want to have my bases covered so that users can access the site even if they have a letter off. How would I go about doing this with Google App Engine?
I would imagine that I need a python handler to do the redirects but what would this look like? Any resources or examples would be great.
You can simply use the self.redirect() and your request will be handled correctly.
class PageHandler(webapp.RequestHandler):
def get(self):
self.redirect('/home/', permanent=True)
You can also set a custom status using the self.response.set_status(301). I would suggest you reading more in the docs: Redirects, Headers and Status Codes.

Googles App Engine, Python: How to get parameters from a log-in pages?

Here is a quote from here:
So in short ... you need to look into login
page, see what params it uses e.g
login=xxx, password=yyy, post it to
that page and you will have to manage
the cookies too, that is where library
like twill etc come into picture.
How could I do it using Python and Google App Engine? Can anybody please give me some clue? I have already asked a question about the authenticated request, but here it seems the matter is different as here I am suggested to look into login page and get parameters, and also I have to deal with cookies.
There are two ways
AS I told you use twill or mechanize, as twill is just a simple wrapper over mechanize you may just use mechanize(http://wwwsearch.sourceforge.net/mechanize/), but to use mechanize you may need to do some hacking see import mechanize module to python script for more details
Do it the hard way and learn something while doing that
Lets see how to login to yahoo
a) look into the page (https://login.yahoo.com/config/login_verify2?&.src=ym) and see what does form look like, you can firebug to inspect instead of looking into raw html.
b) form has login and passwd two field, Plus some more hidden fields lets ignore them for now, so till now we have
form action url= "https://login.yahoo.com/config/login?"
form_data = {'login' : 'my_login', 'passwd' : 'my_passwd'}
c) we can post above data to the correct post url, and it may work but usually we will need to go to other pages and if we do not have cookie it will ask again for login. so lets use a cookie jar e.g.
jar = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(jar))
form_data = urllib.urlencode(form_data)
# data returned from this pages contains redirection
resp = opener.open(url, form_data)
d) now the page from yahoo, redirects to other pages, e.g. if I want to see mail page, i will now go to that and cookies will take care of authentication e.g.
resp = opener.open('http://mail.yahoo.com')
print resp.read()
If you see printout it says , "xxxx| logout , Hmm... your browser is not officially supported." that means it has logged me in :), but as yahoo mail is a ajax page and doesn't support my simple scripting browser, we can get past this tool by spoofing browser type, and can do lots of stuff.
Here is the final code
import urllib, urllib2, cookielib
url = "https://login.yahoo.com/config/login?"
form_data = {'login' : 'your-login', 'passwd' : 'your-pass'}
jar = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(jar))
form_data = urllib.urlencode(form_data)
# data returned from this pages contains redirection
resp = opener.open(url, form_data)
# yahoo redirects to http://my.yahoo.com, so lets go there insetad
resp = opener.open('http://mail.yahoo.com')
print resp.read()
You should look into mechanzie code or links like this http://www.voidspace.org.uk/cgi-bin/voidspace/downman.py?file=cookielib_example.py to see how they do it.
we can post this data
This is not app engine or python specific. You need to get familiar with how POST and GET work. When you log into a typical web site, your browser is sending a POST to the web server, with a bunch of parameters. You can see what the parameters are called by viewing the source of the web page in question, and looking for the login form. Once you know the names of the parameters, you can include them in your POST to the web site. The web site will then return back a cookie, that would normally be stored in your browser. Since you are trying to simulate a browser, you would need to store this cookie yourself, and send it along when you try to request further pages from that particular site.
I am not sure if I understood your question, but if you want the GET parameters, with webapp, it would be something like this:
login = self.request.get('login')
password = self.request.get('password')
More information on dealing with forms is available here
You should also try the user service if want a quick way to authenticate your users.

Resources