I am using Swagger 2.0 and Swagger UI 3.0.3.
In my api_definition.yaml I have the following before my paths:
swagger: '2.0'
################################################################################
# Host, Base Path, Schemes and Content Types #
################################################################################
# Metadata
info:
version: v1
title: Microservice
description: Microservice API!
host: sandbox
basePath: '/apps/fiji/v1'
schemes:
- http
securityDefinitions:
apikey:
type: apiKey
name: X-Access-Token
in: header
security:
- apikey: []
produces:
- application/json
consumes:
- application/json
This adds an Authorize button the the Swagger UI where the user can paste in their API key. I would like this API key to be sent in the request header of every request. This does not happen though and I'm not sure why. Am I missing something?
EDIT:
The request seems to send and I get back 401 Unauthorized.
Chrome Dev Tools shows the following Request Headers:
GET /apps/fiji/v1/getCPICountries HTTP/1.1
Host: sandbox
Connection: keep-alive
accept: application/json
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
content-type: application/json
Referer: http://sandbox/apps/fiji/vendor/swagger-ui/dist/index.html?url=http://sandbox/apps/fiji/swagger/api_definition.yaml
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
I have the paths set up as:
# API Paths
paths:
# getCPICountries endpoint
/getCPICountries:
# HTTP operations
get:
# Describe this verb here. Note: you can use markdown
description: |
Returns a list of countries and country codes
produces:
- application/json
security:
- auth:
- role_admin
# Expected responses for this operation:
responses:
# Response code
200:
description: Successful response
# A schema describing your response object.
# Use JSON Schema format
schema:
properties:
data:
type: array
items:
$ref: '#/definitions/CPIResponse'
And definitions as follows:
definitions:
CPIResponse:
type: object
UserObject:
type: object
properties:
email:
type: string
id:
type: number
orgId:
type: number
firstName:
type: string
lastName:
type: string
The problem was that I override security in my paths. I need to remove the following:
security:
- auth:
- role_admin
Related
Super basic (video) but the title is nearly my comment to Top 3 ways to run your containers on Google Cloud
User Authentication (content) in 2020 about api gateway from endpoints
Maybe a focal point for an answer could be the app engine role for api gateway in 2022. swagger.yaml (#comment)
# openapi2-run.yaml
swagger: "2.0"
info: # >1 API/service; spec x-google-api-name OpenAPI document extension.
title: backbank # mastercard-backbank # API_ID optional-string
#https://cloud.google.com/api-gateway/docs/get-started-cloud-run
description: node cloud run api mastercard p.12 customer keys # Sample API on API Gateway with a Cloud Run backend
version: 0.0.1
security:
- firebase: []
securityDefinitions: #https://cloud.google.com/api-gateway/docs/authenticating-users-firebase
firebase: #bearer https://cloud.google.com/endpoints/docs/openapi/openapi-extensions
authorizationUrl: "" # empty for firebase frm bearer Authorization?
flow: "implicit"
type: "oauth2"
x-google-issuer: "https://securetoken.google.com/vaumoney"
x-google-jwks_uri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken#system.gserviceaccount.com"
x-google-audiences: "vaumoney"
host: "vault-co.in"
basePath: "/" # https://stackoverflow.com/questions/71258737/making-a-cloud-firestore-rest-api-call-through-cloud-endpoints
#When the basePath property is configured in the service configuration as well,
#this header applies only to URL paths that are prefixed by the basePath property value.
#URLs that aren't part of the basePath aren't passed through regardless of the x-google-allow property.
schemes:
- https
consumes:
- application/json
produces:
- application/json
#x-google-allow:
#all
#jwt_audience: https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken#system.gserviceaccount.com/vaumoney
#x-google-endpoints:
#- name: "vault-co.in"
#allowCors: True
paths:
/:
get:
summary: Yes Hello cloud run (api gateway, load balance) service
operationId: get
x-google-backend:
address: https://vault-co.in:8080 # APP_URL endpoint(s)
protocol: h2
responses:
200:
description: This is a (Non-Graphical) Application Programming Interface
#schema:
#type: string
#default: '''ello guv'''
default:
description: Something is wrong
#schema:
#type: string
#default: '''some not 200'''
options:
summary: Enable CORS with headers
operationId: options
x-google-backend:
address: https://vault-co.in:8080 # APP_URL endpoint(s)
jwt_audience: https://vault-co.in
protocol: h2
description: |
Origin, Methods and Headers allowing headers potentially requested
tags:
- CORS
responses:
200:
description: OPTIONS responding headers
headers:
Access-Control-Allow-Origin:
type: string
#$ref: '#/definitions/String'
default: "'i7l8qe.csb.app'"
Access-Control-Allow-Methods:
type: string
default: "'GET,POST'"
Access-Control-Allow-Headers:
type: string
default: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
403:
description: OPTIONS responding headers
headers:
Access-Control-Allow-Origin:
type: string
default: "'i7l8qe.csb.app'" # '''vau.money'''
Access-Control-Allow-Methods:
type: string
default: "'GET,POST'"
Access-Control-Allow-Headers:
type: string
default: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
#content: {}
default:
description: Something is wrong
#type: string
#default: '''some not 200'''
post:
summary: Respond properly indeed
operationId: posted
x-google-backend:
address: https://vault-co.in:8080 # APP_URL endpoint(s)
jwt_audience: https://vault-co.in
protocol: h2
description: |
Successful api fetch
parameters:
- name: pageOffset
in: body
required: true
schema:
type: object
properties:
pageOffset:
description: pageOffset is required, try 0
type: string
pageLength:
description: pageLength is required, try 10
type: string
postalCode:
description: postalCode is required, try 11101
type: string
responses: # https://swagger.io/docs/specification/describing-responses/
default: #200
description: post result
#content:v3 application/json:
schema:
type: object
description: response ok
required:
- results
properties:
results:
#collectionFormat: csv
type: array
default: []
items:
type: string
meta:
type: object
properties:
title:
type: string
description:
type: string
I repeat attempts in seriatim:
gcloud api-gateway gateways delete backbank --location=us-central1
gcloud api-gateway api-configs delete backbank --api=backbank
gcloud api-gateway api-configs create backbank --api=backbank --openapi-spec=swagger.yaml --project=vaumoney --backend-auth-service-account=vaumoney#appspot.gserviceaccount.com
(a) gcloud endpoints services deploy swagger.yaml --project=vaumoney
(b) gcloud services enable vault-co.in (Principal-role permission name: "firebase-adminsdk")
gcloud run deploy backbank \
--image="gcr.io/vaumoney/endpoints-runtime-serverless:2.38.0-vault-co.in-2022-09-08r2" \
--set-env-vars ESPv2_ARGS=^++^--cors_preset=cors_with_regex++--cors_allow_origin_regex=^https:[/][/]i7l8qe.csb.app$++--cors_allow_methods=GET,POST,OPTIONS++--cors_allow_headers=Origin,Content-Type,Authorization,Referrer-Policy++--cors_allow_credentials \
--platform managed --project vaumoney
Of course, I incessantly get this:
The request was not authenticated. Either allow unauthenticated invocations or set the proper Authorization header. Read more at https://cloud.google.com/run/docs/securing/authenticating Additional troubleshooting documentation can be found at: https://cloud.google.com/run/docs/troubleshooting#unauthorized-client
But OPTIONS might be the problem (albeit "" on GET):
"This would be really useful for us, we're using cloud run for all our microservices and want to call these from a SPA via API Gateway." "We're back to Cloud Endpoints and ESPv2 for the time being, but we 100% see the benefits of the managed API Gateway, should CORS support be available for gRPC requests."
What am I to do?
I am using Swagger 2.0.
Facing the error on UI as:
{"messages":["attribute responses.responses.bad$ref is not of type object"],"schemaValidationMessages":[{"level":"error","domain":"validation","keyword":"oneOf","message":"instance failed to match exactly one schema (matched 0 out of 2)","schema":{"loadingURI":"http://swagger.io/v2/schema.json#","pointer":"/definitions/parameter"},"instance":{"pointer":"/parameters/bad$ref"}}]}
It's a YAML based documentation with the following file referencing in the main swagger.yaml.
swagger: '2.0'
info:
$ref: ./info/index.yaml
host: example.net
basePath: /api/v1
tags:
- name: Name
description: description
schemes:
- http
- https
produces:
- application/json
consumes:
- application/json
parameters:
$ref: ./parameters/index.yaml
responses:
$ref: ./responses/index.yaml
paths:
$ref: ./paths/index.yaml
definitions:
$ref: ./definitions/index.yaml
externalDocs:
description: Find out more about Swagger
url: 'http://swagger.io'
Folder structure:
The parameters/index.yaml and responses/index.xml files are empty. This works perfectly in the Swagger Editor.
I used the Spring REST service implementation to learn Swagger.
Service on GET - http://localhost:8080/greeting?name=Betlista returns
{
"id":5,
"content":"Hello, Betlista!"
}
So I created YAML file for Swagger as:
swagger: "2.0"
info:
version: "0.0.1-SNAPSHOT"
title: "Spring REST"
host: "localhost:8080"
basePath: "/"
tags:
- name: "Greeting"
schemes:
- "http"
paths:
/greeting:
get:
operationId: "greeting"
produces:
- "application/json"
parameters:
- name: "name"
in: "query"
required: false
type: "string"
responses:
"200":
description: "successful operation"
schema:
$ref: "#/definitions/GreetingResponse"
definitions:
GreetingResponse:
type: "object"
properties:
id:
type: "integer"
content:
type: "string"
The problem is, when I tried to execute it using "Try it out" button.
It seems (from Chrome's Network tab in developer tools) like there is no response:
...while regular call in browser works fine
edit: as I mentioned in comments, I verified curl generated by swagger and it works as expected - curl -X GET "http://localhost:8080/greeting?name=Betlista" -H "accept: application/json"
At the moment I'm looking into CORS topic (which makes no sense to me as documentation and service are both on localhost), I see in Chrome console this:
This is in fact problem of the service, not of the Swagger Editor.
I'm still looking for a solution, which is described here:
CORS uses special HTTP headers to allow cross-domain requests. The "try it out" feature requires the following headers in API responses:
Access-Control-Allow-Origin: https://host.from.which.the.request.came
Vary: Origin
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: ResponseHeader1, ResponseHeader2, ...
I tried to use Spring REST sevice with CORS, which on curl -I http://localhost:8080/greeting?name=Betlista returns:
HTTP/1.1 200
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
Content-Length: 37
Date: Mon, 02 Nov 2020 13:42:15 GMT
but this is still not working...
As I said, it's not the Swagger Editor problem, but service problem.
CORS check can be turned off in Chrome starting it chrome.exe --disable-web-security --user-data-dir=/tmp as described here which is of course not recommended, so I consider this as a workaround only.
What I used at the end was this - https://stackoverflow.com/a/47022289/384674
edit: later I used - https://stackoverflow.com/a/40300363/384674
I have an API that is far from standard, and I want to create Swagger docs for it. Since it's so far from standard I won't be able to generate anything, instead I'll have to do it manually.
I followed the instructions and created the "hello-world" project, I have been trying to edit this to call my own API instead. A simple GET endpoint returning a JSON list of objects.
I am assuming I can ignore everything that has to do with controllers and mocks etc since this API already returns json data if I call it through postman. I.e its a working API and all I want Swagger for is documentation.
Unfortunately I only get an "ERROR Server not found or an error occurred" when trying it out, but if I browse to the URL it's using it works fine. So I assume there is something I am missing that Swagger needs. Keep in mind I have not change any configs or anything else in this hello-world project, only the editor.
Here is my Yaml:
swagger: "2.0"
info:
version: "0.0.1"
title: Hello World App
# during dev, should point to your local machine
host: localhost
# basePath prefixes all resource paths
basePath: /appname/api/v1/object
#
schemes:
# tip: remove http to make production-grade
- https
# format of bodies a client can send (Content-Type)
consumes:
- application/json
# format of the responses to the client (Accepts)
produces:
- application/json
paths:
/campaign/:
get:
description: Get all campaigns
# used as the method name of the controller
operationId: hello
responses:
"200":
description: Success
schema:
# a pointer to a definition
$ref: "#/definitions/HelloWorldResponse"
# responses may fall through to errors
default:
description: Error
schema:
$ref: "#/definitions/ErrorResponse"
# complex objects have schema definitions
definitions:
HelloWorldResponse:
required:
- message
properties:
message:
type: string
ErrorResponse:
required:
- message
properties:
message:
type: string
Here is the request it tries to send, which looks correct:
GET https://localhost/appname/api/v1/object/campaign/ HTTP/1.1
Host: localhost
Accept: application/json
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,fa;q=0.6,sv;q=0.4
Cache-Control: no-cache
Connection: keep-alive
Origin: http://127.0.0.1:62430
Referer: http://127.0.0.1:62430/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0
README.md on https://github.com/swagger-api/swagger-node says 'Kick the tires. Your API is live while you edit (Did we mention no code?)' -> 'Quit faking' on the next step.
So I was under impression that Swagger will generate a fake API for me.
However, if I use such swagger.yaml:
swagger: '2.0'
info:
title: test
description: test
version: "1.0.0"
host: localhost:10010
schemes:
- https
basePath: /api
produces:
- application/json
- text/event-stream
consumes:
- application/json
paths:
/pages:
get:
summary: test
description: test
responses:
200:
description: pages
schema:
type: array
items:
$ref: '#/definitions/Page'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
(where definitions are also given in config)
I receive 404 in both curl http://localhost:10010/api/pages and swagger editor (swagger project edit). I know about x-swagger-router-controller thing but I expected it to work out of the box. Am I doing something wrong?
I should've read the docs more carefully. Swagger gives us the mock mode (swagger project start -m)