Thanks, Massimo!  I think that retrieving and deleting the token in
request.args(0) is just what I needed.

And the @auth.requires_login() was an accidental inclusion of code
from when I used basic authentication.  I had the API working with
basic authentication before I decided to go with token-based
authentication.  I don't need or intend to use two different
authentication methods.

Thanks again,

Eric

On Sep 15, 11:15 pm, Massimo Di Pierro <[email protected]>
wrote:
> 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()

Reply via email to