Looking at your code again:
@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()
I see two problems:
1)
you have both @auth.requires_login() which only works if you enable
auth.allow_basic_login = True
and you have token authentication. Are you sure you want two
authentications one on top of the other?
2)
call is a method and cannot take arguments.
If your intention is passing the token as request.args(0) simply do:
def call():
token = request.args(0) # grab the 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)
del request.args[0] # make sure you remove the token else you
may mess-up some services.
return service()
else:
raise Exception()
On Sep 15, 2:46 pm, Eric <[email protected]> wrote:
> 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()