OK, here's where my background as a non-CS/humanities major starts to hurt. I'm trying to implement a token authentication for a web service using RPC. I've also developed a sign-up/payment website for the web service that uses web2py with auth. I had the service working fine using basic authentication, but then I realized that my target audience may not always use a client with basic authentication enabled, plus a token authentication system offers me other advantages that I would like.
Anyway, I need advice on where exactly is best to check for the token. Intuitively, it seems reasonable to check for the token in the call function that I've exposed, but what is confusing me is the fact that all the arguments passed by the call go to the decorated RPC function that is called. Indeed, when I check the token in the exposed call action and use curl to make the call using a valid token, I get a "invalid function (api/call)" error. So how would I should I pass a token to the exposed call action in addition to passing other arguments to the various linked actions? Or do I need to check for the token inside each of my remote procedures? Also, is there a good way to cache the token, or will I need to check it on every call? Finally, I had a counter working well with basic authentication to limit calls to a certain number per month. I guess if I have to check for the token inside each of my remote procedures, then that's also where I´ll need to put the counter. This would seem to make for messy and repetitive code, but I'm not sure what else to do. Would anyone like to jump in or point me to a pertinent resource? I'd be very grateful. Django has a token API plugin at: https://github.com/jpulgarin/django-tokenapi/tree/master/tokenapi but I'm not able to extrapolate from their plugin to my app. ####### #model## ################## db.define_table('subscription', Field('id','id'), Field('token', label=T('User Token')), Field('my_calls', type='integer', default=100, label=T('User Calls'),writable=False,readable=False), Field('subscription_method', 'reference method', required=True, label=T('Subscription Method')), Field('is_active','boolean',default=False, label=T('Active'),writable=False,readable=False), Field('created_on','datetime',default=request.now, label=T('Created On'),writable=False,readable=False), Field('modified_on','datetime',default=request.now, label=T('Modified On'),writable=False,readable=False, update=request.now), Field('created_by',db.auth_user,default=auth.user_id, label=T('Created By'),writable=False,readable=False), Field('modified_by',db.auth_user,default=auth.user_id, label=T('Modified By'),writable=False,readable=False, update=auth.user_id), format='%(plan)s', migrate=settings.migrate) ############ ##controller#### # coding: utf8 from gluon.tools import Service service = Service(globals()) @service.run def my_function1(foo,bar): ... return response.body.getvalue() @service.run def my_function2(foo,bar): ... return response.body.getvalue() @auth.requires_login() def call(token): row = db(db.subscription.token == token).select().first() my_number = row.my_calls if my_number > 0 & my_token == token: db(db.subscription.token == my_token).update(my_calls=db.subscription.my_calls-1) return service() else: raise Exception()