Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何从android应用程序连接到Odoo数据库_Python_Json_Python 3.x_Odoo_Odoo 11 - Fatal编程技术网

Python 如何从android应用程序连接到Odoo数据库

Python 如何从android应用程序连接到Odoo数据库,python,json,python-3.x,odoo,odoo-11,Python,Json,Python 3.x,Odoo,Odoo 11,我正在开发一个Android应用程序,我想从Odoo服务器检索数据 为此,我在Odoo中开发了一个自定义模块,在其中我创建了一个控制器 我的控制器: 当我使用auth='public'时,此函数工作正常,但当我使用auth='user'时,我得到以下json响应: 答复[200] { u'jsonrpc': u'2.0', u'id': None, u'error': { u'message': u'Odoo Session Expir

我正在开发一个Android应用程序,我想从Odoo服务器检索数据

为此,我在Odoo中开发了一个自定义模块,在其中我创建了一个控制器

我的控制器: 当我使用
auth='public'
时,此函数工作正常,但当我使用
auth='user'
时,我得到以下json响应:

答复[200]

{  
    u'jsonrpc': u'2.0',   
    u'id': None,   
    u'error': {  
        u'message': u'Odoo Session Expired',   
        u'code': 100,  
        u'data': {  
            u'debug': u'Traceback (most recent call last):  
                      File "/usr/lib/python3/dist-packages/odoo/http.py", line 650, in _handle_exception  
                      return super(JsonRequest, self)._handle_exception(exception)  
                      File "/usr/lib/python3/dist-packages/odoo/http.py", line 310, in _handle_exception  
                      raise pycompat.reraise(type(exception), exception, sys.exc_info()[2])  
                      File "/usr/lib/python3/dist-packages/odoo/tools/pycompat.py", line 87, in reraise  
                      raise value  
                      File "/usr/lib/python3/dist-packages/odoo/addons/http_routing/models/ir_http.py", line 342, in _dispatch  
                      cls._authenticate(func.routing[\'auth\'])  
                      File "/usr/lib/python3/dist-packages/odoo/addons/base/ir/ir_http.py", line 117, in _authenticate  
                      getattr(cls, "_auth_method_%s" % auth_method)()  
                      File "/usr/lib/python3/dist-packages/odoo/addons/base/ir/ir_http.py", line 90, in _auth_method_user  
                      raise http.SessionExpiredException("Session expired")  
                      odoo.http.SessionExpiredException: Session expired',   
            u'exception_type': u'internal_error',   
            u'message': u'Session expired',   
            u'name': u'odoo.http.SessionExpiredException',  
            u'arguments': [u'Session expired'] 
        }  
    }  
}
我的工作基于,这是一份官方的奥多文件,但问题如下:

1它要求我在每个函数中写入管理员密码,这似乎很危险

2身份验证后,我获得了我的用户id,但没有会话令牌。那么,如何使用
auth='user'
通知我的函数我已连接到哪个用户

下面是我测试调用的脚本:

import requests
import json

url_connect = "<my url>/user/login"
url = "<my url>/user/getInfo"
headers = {'Content-Type': 'application/json'}
data_connect = {
                "params": {
                           "email": "<my test account email>",
                           "password": "<my test account password>",
                }
    }
data = {
        "params": {
                   "token": <my test account id>,
            }
       }
data_json = json.dumps(data)
r = requests.get(url=url_connect, data=json.dumps(data_connect), headers=headers)
print(r)
print(r.json())
r = requests.get(url=url, data=data_json, headers=headers)
print(r)
print(r.json())
导入请求
导入json
url_connect=“/user/login”
url=“/user/getInfo”
headers={'Content-Type':'application/json'}
数据连接={
“参数”:{
“电子邮件”:“,
“密码”:“,
}
}
数据={
“参数”:{
“代币”:,
}
}
data_json=json.dumps(数据)
r=requests.get(url=url\u connect,data=json.dumps(data\u connect),headers=headers)
印刷品(r)
打印(r.json())
r=requests.get(url=url,data=data\u json,headers=headers)
印刷品(r)
打印(r.json())
需要注意的事项:

  • 从不在GET请求中发送凭据
  • 所有Odoo RPC请求都是POST请求
  • 如果使用/web/session/authenticate
  • 外部API拟在odoo框架之外使用。开发模块时,如果在模型中,则使用self.env[''],如果在控制器中,则使用http.request.env['']
  • 调用/web/session/authenticate返回一个包含会话id的json,您必须在cookies中将其传递给后续请求,直到调用/web/session/destroy注销
以下是使用/web/session/autenticate的示例:

import requests
import json

url_connect = "http://localhost:8069/web/session/authenticate"
url = "http://localhost:8069/web/session/get_session_info"

headers = {'Content-Type': 'application/json'}

data_connect = {
    "params": {
        "db": "demo1",
        "login": "admin",
        "password": "admin",
    }
}

data = {}

session = requests.Session()

r = session.post(url=url_connect, data=json.dumps(data_connect), headers=headers)

if r.ok:
    result = r.json()['result']

    if result.get('session_id'):
        session.cookies['session_id'] = result.get('session_id')

r = session.post(url=url, data=json.dumps(data), headers=headers)
print(r)
print(r.json())
要从控制器获取信息,您可以使用request.env.user,它目前保存已登录的用户,并且由于您指定了auth='user',因此它必须是有效的。示例代码可能如下所示:

from odoo.http import request

class UserController(http.Controller):
  @http.route('/user/getInfo', type='json', method='POST', auth='user')
  def get_info(self, **kwargs):
    current_user = request.env.user

    Response.status = '200 Succesful operation'
    json_result = {'info': current_user.info}
    return json.dumps(json_result)

写得很好,你已经做了家庭作业。这对我来说非常有用,可以使用api样式的请求对移动用户会话进行身份验证

@http.route([
    '/m/login/email',
], type='http', auth="public", website=True, methods=["POST"], csrf=False)
def users_login_email(self, **kwargs):
    if kwargs:
        data = json.loads(kwargs.keys()[0])
    else:
        data = json.loads(request.httprequest.data)

    email = data.get('email')
    password = data.get('password')

    if not request.session.db:
        setup_db()
    uid = request.session.authenticate(request.session.db, email, password)
    if uid:
        return self._user_details(uid)
    body = json.dumps({"body": ["Credenciales Incorrectas"]})
    return werkzeug.wrappers.Response(body, status=403, headers=[
        ('Content-Type', 'application/json'), ('Content-Length', len(body))
    ])
另外,我没有使用
auth='user'
来防止Odoo干扰重定向和web内容检查。我在需要经过身份验证的用户返回正确的HTTP错误状态代码的控制器路由中使用此注释包装器

def check_user(f):
    @functools.wraps(f)
    def wrap(*args, **kwargs):
        if not request.session.db:
            setup_db()

        request.uid = request.session.uid

        if not request.uid:
            body = json.dumps({"body": ["Session Expired"]})
            return werkzeug.wrappers.Response(body, status=403, headers=[
                ('Content-Type', 'application/json'), ('Content-Length', len(body))
            ])

        return f(*args, **kwargs)

    return wrap
您可以这样使用它:

@check_user
@http.route([
    '/m/<int:shop_id>/cart/info',
], type='http', auth="public", website=True)
def cart_info(self, shop_id, **kwargs):
@check\u用户
@http.route([
“/m//cart/info”,
],type='http',auth=“public”,website=True)
def购物车信息(自身、店铺id、**kwargs):

我还尝试使用“/web/session/authenticate”进行连接,这是odoo的内置控制器。它工作正常,并返回会话ID。但是我如何使用这个会话ID呢?我试图将它传递到我的参数中,但效果并不好,我仍然有相同的答案“Odoo会话已过期”“”,感谢没有基本Odoo http重定向的解决方案。这可能会成为一个问题,如果是这样,我会尝试你的解决方案。
def check_user(f):
    @functools.wraps(f)
    def wrap(*args, **kwargs):
        if not request.session.db:
            setup_db()

        request.uid = request.session.uid

        if not request.uid:
            body = json.dumps({"body": ["Session Expired"]})
            return werkzeug.wrappers.Response(body, status=403, headers=[
                ('Content-Type', 'application/json'), ('Content-Length', len(body))
            ])

        return f(*args, **kwargs)

    return wrap
@check_user
@http.route([
    '/m/<int:shop_id>/cart/info',
], type='http', auth="public", website=True)
def cart_info(self, shop_id, **kwargs):