sanic-auth icon indicating copy to clipboard operation
sanic-auth copied to clipboard

doesnt play well with sanic_session

Open quillfires opened this issue 2 years ago • 3 comments

doesnt play well with sanic_session while assigning user to request.ctx.session in the middleware. user is not saved and manually saving is not working since auth takes over the session and user data is limited by this module. have to fetch user data from the db by using the uid from the _auth and this makes two calls to the db. im using MongoDBSessionInterface of the sanic_session

quillfires avatar Jul 23 '23 04:07 quillfires

Could you show me some code to demonstrate that, I am having hard time to understand the scenario, thanks.

pyx avatar Oct 01 '23 06:10 pyx

i mean mongo session. had to do this work around:

from app_auth import Auth
from sanic_session import MongoDBSessionInterface
from sanic_motor import BaseModel

app = Sanic("app")
app.config.AUTH_LOGIN_ENDPOINT = 'login'
app.config.AUTH_LOGOUT_ENDPOINT = 'logout'
app.config.AUTH_COOKIE_NAME = 'session'
app.config.SESSION_NAME = 'session'


session_interface = MongoDBSessionInterface(app)
auth = Auth()
auth.setup(app)
BaseModel.init_app(app)

class SessionModel(BaseModel):
    __coll__ = 'session'

async def load_user(token):
    try:
        name = token['user_name']
    except:
        name = token['name']
    user = await User.get({"user_name": name})
    if user:
        user["_id"] = str(user["_id"])
        user["id"] = str(user["_id"])
        del user.password
        return user
    return None

auth.load_user = (load_user)

async def current_user(request):
    user = request.ctx.session.get('user', None)
    if user:
        return user
    else:
        token = request.ctx.session.get('_auth', None)
        if token is not None:
            return await auth.load_user(token)
    return None

auth.current_user = (current_user)


@app.on_request
async def inject_session(request):
    if not hasattr(request.ctx, 'session'):
        session = await session_interface.open(request)
        request.ctx.session = session
    user = await auth.current_user(request)
    if not request.ctx.session.get('user') and request.ctx.session.get('_auth'):
        await SessionModel.update_one({"sid":request.ctx.session.sid}, {"$set": {"user": user}})
        request.ctx.session['user'] = user


@app.on_response
async def save_session(request, response):
    await session_interface.save(request, response)

I wasnt able to use conveniently just injecting user to request.ctx.session

quillfires avatar Oct 01 '23 08:10 quillfires

You mentioned 'work around', so this is what is working, right? Could you show me the failed case, or the way you intended to code? Thanks.

pyx avatar Oct 01 '23 09:10 pyx