How to run custom code at login with flask-securit

2019-04-23 03:34发布

问题:

I am new to flask, but moderately proficient in python - I have a flask app that uses flask-security for user authentication. I would like to add some additional functionality to the user login process. Specifically, I need to save the user's auth_token (which I have set up to be a one-time-use token) to the db when they login, and remove it when they log out. The issue comes because flask-security does not (to my knowledge) expose the machinery of logging in directly to the developer. As far as I can tell from the code, it imports flask-login, which uses a login_user function.

I started out by trying to override this function by importing flask.ext.login (which normally, I would not need to do) and redefining the function as follows:

import flask.ext.login as a
def new_login_user():
    ...copy of existing function goes here...
    ...Plus new stuff with current_user.get_auth_token()...
a.login_user = new_login_user

however, I got hit with all sorts of namespace issues, and it seems like a really ugly way to do it.

I was thinking there might be a way to do it with a decorator, but I am new to flask, and have not used decorators much regardless.

Any ideas on what the best way to approach this might be? for context, I want the auth_token in the db, because I need to pass off the website authentication to another process, which also accesses the db. The other process is an API server using websockets. I don't want to combine the processes.

回答1:

I think using a signal decorator seems to be the easiest-- in the following example on_user_logged_in should be called when a user logs into your app. More info in the docs.

from flask.ext.login import user_logged_in

@user_logged_in.connect_via(app)
def on_user_logged_in(sender, user):
    log_auth_token(user.get_auth_token()) # or whatever.


回答2:

Best keep it clean, write your own new_login_user function and use that whenever you would otherwise use flask.ext.login.login_user. You could put your new_login_user into its own file and import it from there.

You could even call it login_user, and never import flask.ext.login.login_user directly.