i'm using Odoo 14 CE
using addon
https://apps.odoo.com/apps/modules/12.0/auth_api_key/
api_key = 123456789
localhost:8069/my_service?api_key=123456789
wher is my configuration went wrong ?
Odoo is the world's easiest all-in-one management software.
It includes hundreds of business apps:
i'm using Odoo 14 CE
using addon
https://apps.odoo.com/apps/modules/12.0/auth_api_key/
api_key = 123456789
localhost:8069/my_service?api_key=123456789
wher is my configuration went wrong ?
If you do not like to use the addon, you can add your own auth method and use the Developer API Key of Odoo 14 (you can add API keys in the preferences now):
class IrHttp(models.AbstractModel):
_inherit = "ir.http"
@classmethod
def _auth_method_my_api_key(cls):
api_key = request.httprequest.headers.get("Authorization")
if not api_key:
raise BadRequest("Authorization header with API key missing")
user_id = request.env["res.users.apikeys"]._check_credentials(
scope="rpc", key=api_key
)
if not user_id:
raise BadRequest("API key invalid")
request.uid = user_id
And then use it
@http.route(..., auth='my_api_key', ...)
For requests, you just need to set the "Authorization: <api_key>" Header.
(Feedback appreciated)
Where should this class go? I've tried putting in my controller file but it's causing a 500 server error.
@Luke the "ir.http" is a model to be put in the /models directory. You just extend the default Odoo "ir.http" model with your API authentication.
Thank you Michael Jurke,
your Explanation is the correct one 👍
In Odoo V14/15 are following auth options existing by default without additional apps:
thing, calendar, outlook, public, user, none
Thank you for your reply, it helps a lot.
FYI on V16 we should use request.update_env(user_id) instead of the request.uid = user_id
This implementation below enables you to use a decorator without further inheritances.
from odoo import SUPERUSER_ID
from odoo.exceptions import ValidationError as VE
from odoo.http import request, db_list
def authenticate(func):
@wraps(func)
def validate_api_key(*args, **kw):
auth_error = messages.get('access')
key = request.httprequest.headers.get('api-key')
if not key:
raise VE(auth_error)
if not request.session.db:
request.session.db = db_list()[0] # here we pick the first available db if the instance is a multi db and db_name has not been set in the odoo.conf
uid = request.env['res.users.apikeys'].with_user(SUPERUSER_ID)._check_credentials(scope='rpc', key=key)
if not uid:
logger.error(f"{func.__name__} auth_error['message']")
raise VE(auth_error)
request.update_env(user=uid) # here we switch the user to the one owning this key
return func(*args, **kw)
return validate_api_key
2. Controller
@authenticate
@route(['/products'], auth="public", type='json', methods=['POST'], csrf=False)
def create_product(self, **kw):
@Luke, try to change @classmethod by @property, for me it works. Thanks @Michael for sharing.
Sorry again @Luke, but @Michael 's code is right but you have to consider putting it as a model, I was confused, maybe like you, and I wrote it into the controller but that's wrong.
Create an account today to enjoy exclusive features and engage with our awesome community!
Sign upRelated Posts | Replies | Views | Activity | |
---|---|---|---|---|
|
5
Dec 20
|
9692 | ||
|
0
Apr 25
|
353 | ||
|
0
Jan 24
|
1991 | ||
|
0
Jul 21
|
2798 | ||
|
1
Apr 25
|
820 |
Hey @Usman, how did you do it?
you can see the answer