odoo 17 后端路由接口认证自定义
odoo 17 后端路由接口认证自定义
在接口中, 我们都知道有3中常用的认证方式
user
用户级认证public
访问时赋予公共用户none
不做任何用户级处理 一般不做数据库重要数据校验, 仅做访问处理
以上是源码提供的三种方式
接下来我们自定义一个认证方式
首先找到的这认证是在 ir.http
模型内完成的, 认真源码如下
@classmethod
def _authenticate(cls, endpoint):
auth = 'none' if http.is_cors_preflight(request, endpoint) else endpoint.routing['auth']
try:
if request.session.uid is not None:
if not security.check_session(request.session, request.env):
request.session.logout(keep_db=True)
request.env = api.Environment(request.env.cr, None, request.session.context)
getattr(cls, f'_auth_method_{auth}')()
except (AccessDenied, http.SessionExpiredException, werkzeug.exceptions.HTTPException):
raise
except Exception:
_logger.info("Exception during request Authentication.", exc_info=True)
raise AccessDenied()
源码中可以看到 getattr(cls, f'_auth_method_{auth}')()
这里匹配并执行, 很明显可以看到调用了这个类的方法 _auth_method_user, _auth_method_public, _auth_method_none
往后继续操作
@classmethod
def _get_public_users(cls):
return [request.env['ir.model.data']._xmlid_to_res_model_res_id('base.public_user')[1]]
@classmethod
def _auth_method_user(cls):
if request.env.uid in [None] + cls._get_public_users():
raise http.SessionExpiredException("Session expired")
@classmethod
def _auth_method_none(cls):
request.env = api.Environment(request.env.cr, None, request.env.context)
这时候我们只需继承 ir.http
模型进行操作, 下面是例子
from odoo import models
from odoo.http import request
class IrHttp(models.AbstractModel):
_inherit = 'ir.http'
@classmethod
def _auth_method_wechat(cls):
user = request.env.ref('xxx.user_wxapp_user_manager') # 给后端用户作为认证
request.uid = user.id
request.user = user
这里以通过添加微信认证wechat
为例, 将模块安装后,系统会增加一个微信认证功能, 更多操作请在方法中编写逻辑
main.py
文件
普通接口访问如下
@http.route('/demo/auth/reload', type='http', auth='user', methods=['GET'], cors='*', csrf=False)
def auth_reload(self):
"""
认证接口, 需要通过用户级认证
"""
return Response(json.dumps({}), status=200, content_type='application/json')
自定义认证访问, 只需修改 auth='wechat'
即可
@http.route('/demo/auth/reload', type='http', auth='wechat', methods=['GET'], cors='*', csrf=False)
def auth_reload(self):
"""
自定义认证接口, 通过 _auth_method_wechat 方法处理用户需求
"""
return Response(json.dumps({}), status=200, content_type='application/json')
最后是模块的目录结构
└─demo
│ __init__.py
│ __manifest__.py
│
├─controllers
│ main.py
│ __init__.py
│
├─models
│ ir_http.py
│ __init__.py
注意, 别忘了将 controllers 和 models
导出到包外