hapijs / nes

WebSocket adapter plugin for hapi routes
Other
502 stars 87 forks source link

Newbie question about authorization header and client.request #273

Closed no-more closed 5 years ago

no-more commented 5 years ago

Hello,

I'm opening a new issue but I think it's directly related to closed one #38

I'm trying to implement websocket and use request on my client side. But I'm still confused about the header. request does not allow authorization for security purpose witch seems fine to me but how can I authenticate myself on the route. According to devinivy in a comment of #38 the auth is handled automatically if already done on connection. But hapi throws an error (child "authorization" fails because ["authorization" is required]) because my route, when used without the websocket requires and authorization token to be present. I'm publishing an automatically generated swagger definition, so making it optional will be visible by the api's users and it's quite counter intuitive for them.

It would be great if nes would automatically fill this field if the websocket connection was authenticated. This way Joi validation would still be ok

What if I'm doing extra validation process in the authentication scheme using additional headers information and maybe async authentication against an other server. It's currently completely bypassed.

Tell me if I'm doing something wrong which could explain this behavior.

Thanks

hueniverse commented 5 years ago

I don't understand your question. If you want to post a short example of what you are trying to do, we can try to help. There are also plenty of useful examples in the tests. Have you looked there?

no-more commented 5 years ago

On the client side, when I'm doing a request this is what I'm doing :

const response = await this.webSocketClient.request({
    path: "/contact/create",
    payload: contactData,
    method: "POST",
    headers: {
        // "authorization": authorization, // here I have to remove authorization as it's not allowed by ness
        "language-code": language_code,
        "Content-Type": "application/json; charset=UTF-8",
        "Accept": "application/json; charset=UTF-8"
    }
});

on the server side I have a route /contact/create which can be used through the websocket client or not. In the case of a non websocket request, I have to ensure the request is authenticated. So I'm using this kind of Joi validation for my route :

{
    headers: {authorization: Joi.string().required() ...},
    payload: definition
}

But this does not work with ness because authorization cannot be provided I have to switch from required to optional which is not what I want in this case because the route is also accessible without the websocket client with a direct http call. When I'm using the websocket authentication was already done on connection and it's forwarded directly to the handler. Which works fine as long as authorization field is not required in my route header. That's why I was wondering if ness (server side) couldn't add dynamically the authorization token before forwarding to the route validation handler.

That was for the first part of my question.

hueniverse commented 5 years ago

If you passed the correct authentication headers when you connected the client, those are passed on with every request automatically for you. You don't need to authenticate each request, just once when you connect. You should never use joi validation for authentication headers, that's just wrong.

This is shown in the example: https://github.com/hapijs/nes#route-authentication

no-more commented 5 years ago

Thanks, I'm aware about ness passing auth data to sub request. But I'm quite surprise about not using joi to validate headers. I'm using hapi-swagger to generate swagger files automatically for all my routes. So I need to define my headers parameters with Joi. But maybe it's the field authentication that I'm miss using to send my token back to the server. Maybe I should rename this field to something else (maybe token). Is that what you meant?

hueniverse commented 5 years ago

You should not use joi to validate authorization headers. You should use an auth scheme to do that. You should also not invent new ways to authenticate a request, especially one that is already authenticated via the nes connection.

no-more commented 5 years ago

I'm using an scheme to authenticate. This scheme read my authentication token from headers['authentication']. Joi is only used to defined what my route is expecting as header, payload ... but I think I should just rename my token parameter to something else than authentication which might be a reserved key word. I think that's what what confusing me from the beginning.

Thanks for you help.

lock[bot] commented 4 years ago

This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions.