簡體   English   中英

如何從Android應用程序連接到Odoo數據庫

[英]How to connect to Odoo database from an android application

我正在開發Android應用程序,我想從Odoo服務器檢索數據。

為此,我在Odoo中開發了一個自定義模塊,在其中我創建了一個控制器。

我的控制器:

import json
import xmlrpc.client as xmlrpclib
from odoo import http
from openerp.http import Response

class resUserController(http.Controller):
    url = '<my url>'
    db = '<name of my database>'

    @http.route('/user/login', type='json', method='GET', auth='public')
    def get_login(self, **kwargs):
        username = kwargs.get('email')
        password = kwargs.get('password')
        common = xmlrpclib.ServerProxy('{}/xmlrpc/2/common'.format(self.url), allow_none=True)

        uid = common.authenticate(self.db, username, password, {})
        if uid:
            Response.status = '200 Succesful operation'
            json_result = {'token': uid}
            return json.dumps(json_result)
        Response.status = '400 Invalid credentials'
        return

當我從python腳本中調用它來嘗試它時,它工作正常,我得到一個<Response [200]>和一個json {u'jsonrpc': u'2.0', u'result': u'{"token": 8}', u'id': None}帶有我連接的帳戶的ID。

但是后來我在同一個控制器中使用其他路由調用了另一個函數,但這次使用auth='user' ,因為我希望用戶只能看到他有權使用的信息。

@http.route('/user/getInfo', type='json', method='GET', auth='user')
def get_info(self, **kwargs):
    uid = 1
    password = '<my admin password>'
    models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(self.url), allow_none=True)
    info = models.execute_kw(self.db, uid, password, 'res.users',
                             'search_read', [[['id', '=', kwargs.get('token')]]],
                             {'fields': ['info']})[0]['invite_code']
    if info:
        Response.status = '200 Succesful operation'
        json_result = {'info': info}
        return json.dumps(json_result)
    Response.status = '404 User not found'
    return

當我使用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'] } } } 

我的工作基於這個文檔 ,這是一個官方的Odoo文檔,但這里有問題:

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())

注意事項:

  • 永遠不要在GET請求中發送憑據
  • 所有Odoo RPC請求都是POST請求
  • 如果使用/ web / session / authenticate,則不需要自定義登錄路由
  • 外部API旨在在odoo框架之外使用。 在開發模塊時,如果在模型中,則使用self.env ['<model>'],如果在控制器中,則使用http.request.env ['<model>']
  • / web / session / authenticate的調用返回一個包含session_id的json,您必須將cookie傳遞給后續請求,直到您調用/ 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):

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM