I have written a simple Tornado app. It has a homepage, if the user is logged in, it says user is logged or else it has a link to login. Here is the full script and I have set up website url as localhost:8000 in my FB app settings :
#!/usr/bin/env python
import os.path
import os
import tornado.auth
import tornado.escape
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define, options
from settings import *
define("port", default=8000, help="run on the given port", type=int)
class Application(tornado.web.Application):
def __init__(self):
handlers = [
(r'/', MainHandler),
(r'/auth/login', LoginHandler),
(r'/auth/logout', LogoutHandler)
]
settings = application_handler_setttings
tornado.web.Application.__init__(self, handlers, **settings)
class MainHandler(tornado.web.RequestHandler):
def get(self):
userID = self.get_secure_cookie('user_id')
if userID:
self.render("index.html")
else:
self.render("login.html")
class LoginHandler(tornado.web.RequestHandler, tornado.auth.FacebookGraphMixin):
@tornado.web.asynchronous
def get(self):
userID = self.get_secure_cookie('user_id')
if self.get_argument('code', None):
self.get_authenticated_user(
redirect_uri='http://localhost:8000/auth/login',
client_id=self.settings['facebook_api_key'],
client_secret=self.settings['facebook_secret'],
code=self.get_argument('code'),
callback=self.async_callback(self._on_facebook_login))
return
elif self.get_secure_cookie('access_token'):
self.redirect('/')
self.authorize_redirect(
redirect_uri='http://localhost:8000/auth/login ',
client_id=self.settings['facebook_api_key'],
extra_params={'scope': 'user_photos, publish_stream'}
)
def _on_facebook_login(self, user):
if not user:
self.clear_all_cookies()
raise tornado.web.HTTPError(500, 'Facebook authentication failed')
self.set_secure_cookie('user_id', str(user['id']))
self.set_secure_cookie('user_name', str(user['name']))
self.set_secure_cookie('access_token', str(user['access_token']))
self.redirect('/')
class LogoutHandler(tornado.web.RequestHandler):
def get(self):
self.clear_all_cookies()
self.render('logout.html')
def main():
tornado.options.parse_command_line()
http_server = tornado.httpserver.HTTPServer(Application())
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
main()
my settings.py file:
import os
application_handler_setttings = dict(
template_path=os.path.join(os.path.dirname(__file__), "templates"),
static_path=os.path.join(os.path.dirname(__file__), "static"),
facebook_api_key= '1...3',
facebook_secret= '7...d',
cookie_secret= 'N...g',
debug=True,
)
Here is the issue. When I authenticate my app and when it redirects back, the url in browser changes and some strange string is present, it is http://localhost:8000/#_=_
. I am not able to understand, why such string is being appended.
Secondly, if I enter any url starting with #, it is not throwing 404 error, because I have not defined any handler. Why is that? For example, even if I enter http://localhost:8000/#fghdgdh
it shows the index page. Well, I find that strange.
Lastly, is it possible to keep all my handler class definitions in in separate files? And also the list of tuple of url and handler functions, is it possible to keep this also in some separate file other than these class definitions and the in the main script?