Odoo中登录接口返回的session_id失效

Odoo中登录接口返回的session_id失效

odoo 版本: 12.0 社区版

登录接口 /web/session/authenticate

将返回结果中的session_id用作其他请求中的身份验证,发现session_id已失效

然后神奇的发现返回的session_id和cookie中存的id不一致

百思不得其解的从源码里找答案

登录方法执行的步骤

web/controllers/main.py 809
@http.route('/web/session/authenticate', type='json', auth="none")
def authenticate(self, db, login, password, base_location=None):
    request.session.authenticate(db, login, password)
    return request.env['ir.http'].session_info()

web/models/ir_http.py 21
 def session_info(self):
        user = request.env.user
        display_switch_company_menu = user.has_group('base.group_multi_company') and len(user.company_ids) > 1
        version_info = odoo.service.common.exp_version()
        return {
            "session_id": request.session.sid,
            "uid": request.session.uid,
            "is_system": user._is_system() if request.session.uid else False,
            "is_admin": user._is_admin() if request.session.uid else False,
            ...}
   

请求中所维护的session

odoo/http.py 1440

请求会先获取session 通过setup_session
不存在则新封装一个
session也可以通过请求头X-Openerp-Session-Id进行指定

def setup_session(self, httprequest):
    # recover or create session
    session_gc(self.session_store)

    sid = httprequest.args.get('session_id')
    explicit_session = True
    if not sid:
        sid =  httprequest.headers.get("X-Openerp-Session-Id")
    if not sid:
       sid = httprequest.cookies.get('session_id')
       explicit_session = False
    if sid is None:
       httprequest.session = self.session_store.new()
    else:
       httprequest.session = self.session_store.get(sid)
    return explicit_session


当登录方法执行,session_id是新生成的一个/cookies中的一个值
而在get_response中,保存了当前会话,默认是重新将当前用户的session进行重新赋值

odoo/http.py 1416
def get_response(self, httprequest, result, explicit_session):
		...
        save_session = (not request.endpoint) or request.endpoint.routing.get('save_session', True)
        if not save_session:
            return response

        if httprequest.session.should_save:
            if httprequest.session.rotate:
                self.session_store.delete(httprequest.session)
                httprequest.session.sid = self.session_store.generate_key()
                if httprequest.session.uid:
                    httprequest.session.session_token = security.compute_session_token(httprequest.session, request.env)
                httprequest.session.modified = True
            self.session_store.save(httprequest.session)

返回的response中的session_id是新生成的

所以导致使用登录接口,返回的session_id已失效

posted @ 2021-09-04 14:05  Henry121  阅读(457)  评论(1编辑  收藏  举报