a-h / rest

Generate OpenAPI 3.0 specifications from Go code.
MIT License
54 stars 20 forks source link

feature request: add support for authentication #11

Open a-h opened 1 year ago

a-h commented 1 year ago

To add JWT authentication to an API, requires this... as per https://swagger.io/docs/specification/authentication/bearer-authentication/

    spec, err := api.Spec()
    if err != nil {
        log.Error("failed to create spec", slog.Any("error", err))
        os.Exit(1)
    }

    spec.Components.SecuritySchemes = map[string]*openapi3.SecuritySchemeRef{
        "bearerAuth": {
            Value: openapi3.NewJWTSecurityScheme(),
        },
    }

    securitySchemeToScopes := openapi3.NewSecurityRequirement()
    securitySchemeToScopes.Authenticate("bearerAuth")
    spec.Security = *openapi3.NewSecurityRequirements().
        With(securitySchemeToScopes)

Since it's so common, maybe it would be better as:

        api.SetAuth(rest.JWTBearerAuth())

    spec, err := api.Spec()
    if err != nil {
        log.Error("failed to create spec", slog.Any("error", err))
        os.Exit(1)
    }

Not sure about how the API would look to support mixed authentication (some handlers authenticated, some open). Maybe that would be out of scope.

the-pawn-2017 commented 6 months ago

I am willing to undertake all this work.Although with some programming experience under my belt, I have only recently started contributing code to the community, specifically through platforms like GitHub, collaborating with others. Your patience may be needed as I navigate linguistic barriers and get accustomed to the workflow processes.

debuggerpk commented 1 week ago

Thank you for your work.

An API generally has some public endpoints and some private endpoints. We set the security per endpoint.

We have an API that has security schema per route, so the method should be available on route as well.

  /auth/teams:
    post:
      summary: Create a new team
      description: Create a new team
      operationId: create-team
      tags:
        - auth
      requestBody:
        description: Team to create
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateTeamRequest"
      security:
        - BearerAuth: []
      responses:
        "201":
          description: Team created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Team"
        "400":
          $ref: "../../shared/v1/schema.yaml#/components/responses/BadRequest"
        "401":
          $ref: "../../shared/v1/schema.yaml#/components/responses/Unauthorized"
        "500":
          $ref: "../../shared/v1/schema.yaml#/components/responses/InternalServerError"

I think the method should be per route.