I just checked myself and yes, I did have to turn it into a string, since whatever object anvil uses is not serializable into a simple object for use in a simple object column. So you could use a text column instead.
user_row = app_tables.users.get_by_id(anvil.users.get_user().get_id())
user_row['context'] = str(anvil.server.context.client)
I have not built it out, but if I were to, I would have a function take the context object “string” and md5 hash it so I didn’t unnecessarily store user info I did not need and put it in a text column in the users table. This function would run in a server call alongside a successful anvil.users.login_with_form().
I would then create a server module security function that would compare the current context object hashed string, with whatever was in the table, and if it did not match, run anvil.users.logout().
I might even create an @decorator for this purpose.
from functools import wraps
def with_user_security(func):
@wraps(func)
def wrapper_func(*args, **kwargs):
if not your_context_compare_function_here():
anvil.users.logout()
#return # ?? how you want to handle security is up to you
func(*args, **kwargs)
return wrapper_func
then later:
@anvil.server.callable
@with_user_security
def any_callable_nmvega_function():
...
So yes,
It should handle itself, if you have most of the important bits of whatever you are doing protected inside the server modules. (Otherwise you really don’t need/have any security anyway)