danielgtaylor / huma

Huma REST/HTTP API Framework for Golang with OpenAPI 3.1
https://huma.rocks/
MIT License
1.71k stars 134 forks source link

Discussion: option to make all APIs registered with security scheme by default #490

Open mskonovalov opened 4 weeks ago

mskonovalov commented 4 weeks ago

The idea is: when adding a new API it is very easy to forget to enable the security (as it is currently per API config). Would it be a good idea if you set a config to make APIs secure by default, that huma.Register will automatically add Security to all APIs, excluding these which opted-out expliacitly?

Currently if I set like this

cfg.Security = []map[string][]string{
        {"bearer": {}},
        {},
    }

the auth becomes optional for all registered APIs.

Please let me know if such option already exists and I just missed it. Or also any suggestions how to implement something like that.

I understand that this type of behavior can be not compatible with the existing code bases, but maybe if it will be a completely new option in the config it may work. Thanks

cardinalby commented 3 weeks ago

I believe it should be solved in more general way via groups functionality, it's the problem not only with security property but with all the operation properties and transformers (that can't be set per operation)

Take a look at my suggestion https://github.com/danielgtaylor/huma/issues/489

With my approach you would:

api := originApi.WithOpHandler(op_handler.AddSecurity(
    map[string][]string{{"bearer": {}}
)

And all the operations registred with api will have the security entry you specified.

The same with all other properties:

v1gr := api.            // all operations registered with v1gr will have:
    AddBasePath("/v1").                            // - "/v1" base path
    AddOpHandler(op_handler.AddTags("some_tag")).  // - "some_tag" tag
    AddMiddlewares(m1, m2)                         // - m1, m2 middlewares

hureg.Get(v1gr, "/cat", ...) // "/v1/cat" with "some_tag" tag and m1, m2 middlewares
hureg.Get(v1gr, "/dog", ...) // "/v1/dog" with "some_tag" tag and m1, m2 middlewares