I run with web2py a rest api in the controller and there my jwt and the token works. In the model I am using fields with default values but this fields are never filled automatically because auth.user is None. I tried to init it manually but it does not work.
Sites.py:
if auth.user is None:
auth = Auth(db, jwt = {'secret_key':'..hnv', 'user_param':"email"})
#auth.jwt()
auth.basic()
#auth.user.update()
I tried also to add the parameter in db.py but no success:
auth = Auth(db,jwt = {'secret_key':'...', 'user_param':"email"}, host_names=configuration.get('host.names'))
Does I expect too much or I am doing something wrong?
auth = Auth(db, jwt = {'secret_key':'...', 'user_param':"email"})
If you instatiate Auth
as above (i.e., adding the JWT functionality), when a request with a JWT token comes in, auth.user
is not immediately populated when the above line is executed. Rather, the token is only read and auth.user
populated when the @auth.allows_jwt()
decorator is executed (i.e., in the requested controller). This means that in your model files where you have your DAL
table definitions, auth.user
(and auth.user_id
and auth.user_groups
) will still be None
during requests authorized via JWT, so you cannot directly use those values as field defaults.
As an alternative, you can instead specify a function as a field default, with the function returning the relevant auth
property:
db.define_table('mytable',
...,
Field('created_by', default=lambda: auth.user_id))
The lambda
function defined above will not be called when the table is defined, but only later when actually creating a record, which presumably will only happen in a controller that has been decorated with @auth.allows_jwt()
(and therefore, auth.user
will have been populated by that point).
Another option is to force auth.user
to be populated in the model file by calling auth.allows_jwt
there (it returns a decorator, but since we are not using it as a decorator, we must instead pass it a no-op function and then call the returned function):
auth = Auth(db, jwt = {'secret_key':'...', 'user_param':"email"})
if not auth.user:
try:
# If there is a token, this will populate `auth.user`,
# `auth.user_id`, and `auth.user_groups` from the token data.
auth.allows_jwt()(lambda: None)()
except:
# An error means the token is absent, expired, or invalid.
pass
Once the above has been executed, you can then use auth.user
and auth.user_id
to specify field defaults in model definitions.