rails (5.0.0.1)
devise (4.2.0)
devise_token_auth (0.1.39)
swagger-ui (2.2.3)
I have a rails 5 api-only app which uses the devise_token_auth gem to handle authentication. With this gem after login app responds with five headers:
"expiry": "1474815305",
"uid": "[email protected]",
"token-type": "Bearer",
"access-token": "TjPCW6LK0ReJBOW0sBR7Pg",
"client": "Yu5UONwdQKUKd--2e5JHVQ"
Additionally I have a global api key which I set via the clientAuthorizations header (no problem at this point).
window.swaggerUi.api.clientAuthorizations.add("key", new SwaggerClient.ApiKeyAuthorization("Authorization", "Token token=ABC123XYZ", "header"));
When sending the login request via swagger api I get the above mentioned headers in a response. How can I add these headers to any other request in the swagger ui without copy&paste? Is there a way to use the swagger security feature (I only found the way for one api key in the documentation).
Can anyone help me? Thanks in advance!
The spec supports multiple headers on its own. Did you try defining it inside the spec itself? Can you share your current definition?
Here is my current definition. I would like to have both authorization headers in every request:
{
"swagger": "2.0",
"info": {
"version": "0.2",
"title": "My backend API",
},
"tags": [
{
"name": "Auth",
"description": "Authentication handling"
},
{
"name": "Companies",
"description": "Company listing"
},
{
"name": "Users",
"description": "User handling"
}
],
"securityDefinitions": {
"client": {
"type": "apiKey",
"name": "client",
"in": "header"
},
"access_token": {
"type": "apiKey",
"name": "access-token",
"in": "header"
}
},
"host": "localhost:3000",
"basePath": "/",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/auth": {
"post": {
"summary": "Creates an user",
"tags": [
"Users"
],
"parameters": [
{
"name": "body",
"in": "body",
"description": "Model",
"schema": {
"$ref": "#/definitions/UserRegistrationWithCompany"
}
}
],
"responses": {
"200": {
"description": "User response"
},
"422": {
"description": "Invalid data"
}
}
}
},
"/auth/sign_in": {
"post": {
"summary": "Authentication by email and password",
"tags": [
"Auth"
],
"parameters": [
{
"name": "body",
"in": "body",
"description": "Model",
"schema": {
"$ref": "#/definitions/UserLogin"
}
}
],
"responses": {
"200": {
"description": "User response"
},
"401": {
"description": "Invalid login credentials"
}
}
}
},
"/auth/sign_out": {
"delete": {
"summary": "Logout",
"tags": [
"Auth"
],
"parameters": [
{
"name": "body",
"in": "body",
"description": "User data",
"schema": {
"$ref": "#/definitions/UserSession"
}
}
],
"responses": {
"200": {
"description": "Success message"
},
"404": {
"description": "User was not found or was not logged in."
}
}
}
},
"/users/me": {
"get": {
"summary": "Returns an user profile",
"tags": [
"Users"
],
"responses": {
"200": {
"description": "User response"
},
"401": {
"description": "Not authorized"
}
}
},
"put": {
"summary": "Updates an user profile",
"tags": [
"Users"
],
"parameters": [
{
"name": "body",
"in": "body",
"description": "Model",
"schema": {
"$ref": "#/definitions/User"
}
}
],
"responses": {
"200": {
"description": "User response"
},
"401": {
"description": "Not authorized"
},
"422": {
"description": "Invalid data"
}
}
}
},
"/users/me/contact_informations": {
"get": {
"summary": "Returns all contact information of a user",
"tags": [
"Users"
],
"responses": {
"200": {
"description": "Contact informations response"
},
"401": {
"description": "Not authorized"
}
}
},
"post": {
"summary": "Creates an user contact entry",
"tags": [
"Users"
],
"parameters": [
{
"name": "body",
"in": "body",
"description": "Model",
"schema": {
"$ref": "#/definitions/ContactInformation"
}
}
],
"responses": {
"200": {
"description": "Contact information response"
},
"401": {
"description": "Not authorized"
},
"422": {
"description": "Invalid data"
}
}
}
},
"/users/me/contact_informations/{id}": {
"put": {
"summary": "Updates an user contact entry",
"tags": [
"Users"
],
"parameters": [
{
"name": "id",
"in": "path",
"type": "integer",
"format": "int64",
"description": "Contact Information ID",
"required": true
},
{
"name": "body",
"in": "body",
"description": "Model",
"schema": {
"$ref": "#/definitions/ContactInformation"
}
}
],
"responses": {
"200": {
"description": "Contact information response"
},
"401": {
"description": "Not authorized"
},
"422": {
"description": "Invalid data"
}
}
},
"delete": {
"summary": "Deletes an user contact entry",
"tags": [
"Users"
],
"parameters": [
{
"name": "id",
"in": "path",
"type": "integer",
"format": "int64",
"description": "Contact Information ID",
"required": true
}
],
"responses": {
"200": {
"description": "Contact information response"
},
"401": {
"description": "Not found"
}
}
}
},
"/companies": {
"get": {
"summary": "Returns all available companies",
"tags": [
"Companies"
],
"responses": {
"200": {
"description": "Array of companies"
}
}
}
},
"/companies/{id}": {
"get": {
"summary": "Returns a company",
"tags": [
"Companies"
],
"parameters": [
{
"name": "id",
"in": "path",
"type": "integer",
"format": "int64",
"description": "Company ID",
"required": true
}
],
"responses": {
"200": {
"description": "Company response"
},
"404": {
"description": "Company not found"
},
"422": {
"description": "Invalid data"
}
}
}
},
"/companies/{id}/employees": {
"get": {
"summary": "Returns all available employees for given company",
"tags": [
"Companies"
],
"parameters": [
{
"name": "id",
"in": "path",
"type": "integer",
"format": "int64",
"description": "Company ID",
"required": true
}
],
"responses": {
"200": {
"description": "Array of employees"
},
"404": {
"description": "Company not found"
}
}
}
}
},
"definitions": {
"ContactInformation": {
"required": [
"name",
"value"
],
"properties": {
"name": {
"type": "string",
"example": "mobile"
},
"value": {
"type": "string",
"example": "+49 151 1 234567890"
}
}
},
"UserLogin": {
"required": [
"email",
"password"
],
"properties": {
"email": {
"type": "string",
"example": "[email protected]"
},
"password": {
"type": "string",
"example": "secret"
}
}
},
"UserRegistration": {
"allOf": [
{
"$ref": "#/definitions/UserLogin"
},
{
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"example": "Test User"
}
}
}
]
},
"UserRegistrationWithCompany": {
"allOf": [
{
"$ref": "#/definitions/UserRegistration"
},
{
"required": [
"company"
],
"properties": {
"company": {
"$ref": "#/definitions/CompanyRegistration"
}
}
}
]
},
"User": {
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"example": "Test User"
}
}
},
"UserSession": {
"required": [
"uid",
"client",
"access-token"
],
"properties": {
"uid": {
"type": "string",
"example": "[email protected]"
},
"client": {
"type": "string",
"example": "NBoZkiULuXXLfyNLgtlD0w"
},
"access-token": {
"type": "string",
"example": "xHdb2q1nLcEG--Cr43F15w"
}
}
},
"CompanyRegistration": {
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"example": "Test company AG"
}
}
},
"Company": {
"allOf": [
{
"$ref": "#/definitions/CompanyRegistration"
},
{
"properties": {
"body": {
"type": "string",
"example": "Lorem ipsum dolor sit amet."
},
"logo": {
"type": "string",
"example": "https://placehold.it/300x300"
}
}
}
]
}
}
}
Okay, so the securityDefinitions just declare which securities can be used, but it doesn't apply them to anything.
To add the security, you'd need to use the security tag - if you want it applied to all operations, you'd describe it at the top-level of the spec.
"security": [
{
"client": [],
"access-token": []
}
]
The above definition says that both client and access-token security definitions are required for the operations.
@webron But with my current implementation I can only authenticate via client or access-token. But I need both together. The ui shows both input fields with separate authenticate buttons.
Which version of the UI do you use?
Sorry, I just saw it's 2.2.3. It should require both and if it doesn't then it's a bug. If you can provide a full spec (with the security definition), I can investigate it further.
Here is my current definition:
{
"swagger": "2.0",
"info": {
"version": "0.2",
"title": "Backend API",
"description": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
},
"tags": [
{
"name": "Auth",
"description": "Authentication handling"
},
{
"name": "Companies",
"description": "Company listing"
},
{
"name": "Users",
"description": "User handling"
}
],
"securityDefinitions": {
"client": {
"type": "apiKey",
"name": "client",
"in": "header"
},
"access_token": {
"type": "apiKey",
"name": "access-token",
"in": "header"
},
"uid": {
"type": "apiKey",
"name": "uid",
"in": "header"
}
},
"security": [
{
"client": [
],
"access-token": [
],
"uid": [
]
}
],
"host": "localhost:3000",
"basePath": "/",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/auth": {
"post": {
"summary": "Creates an user",
"tags": [
"Users"
],
"parameters": [
{
"name": "body",
"in": "body",
"description": "Model",
"schema": {
"$ref": "#/definitions/UserRegistrationWithCompany"
}
}
],
"responses": {
"200": {
"description": "User response"
},
"422": {
"description": "Invalid data"
}
}
}
},
"/auth/sign_in": {
"post": {
"summary": "Authentication by email and password",
"tags": [
"Auth"
],
"parameters": [
{
"name": "body",
"in": "body",
"description": "Model",
"schema": {
"$ref": "#/definitions/UserLogin"
}
}
],
"responses": {
"200": {
"description": "User response"
},
"401": {
"description": "Invalid login credentials"
}
}
}
},
"/auth/sign_out": {
"delete": {
"summary": "Logout",
"tags": [
"Auth"
],
"parameters": [
{
"name": "body",
"in": "body",
"description": "User data",
"schema": {
"$ref": "#/definitions/UserSession"
}
}
],
"responses": {
"200": {
"description": "Success message"
},
"404": {
"description": "User was not found or was not logged in."
}
}
}
},
"/users/me": {
"get": {
"summary": "Returns an user profile",
"tags": [
"Users"
],
"responses": {
"200": {
"description": "User response"
},
"401": {
"description": "Not authorized"
}
}
},
"put": {
"summary": "Updates an user profile",
"tags": [
"Users"
],
"parameters": [
{
"name": "body",
"in": "body",
"description": "Model",
"schema": {
"$ref": "#/definitions/User"
}
}
],
"responses": {
"200": {
"description": "User response"
},
"401": {
"description": "Not authorized"
},
"422": {
"description": "Invalid data"
}
}
}
},
"/users/me/contact_informations": {
"get": {
"summary": "Returns all contact information of a user",
"tags": [
"Users"
],
"responses": {
"200": {
"description": "Contact informations response"
},
"401": {
"description": "Not authorized"
}
}
},
"post": {
"summary": "Creates an user contact entry",
"tags": [
"Users"
],
"parameters": [
{
"name": "body",
"in": "body",
"description": "Model",
"schema": {
"$ref": "#/definitions/ContactInformation"
}
}
],
"responses": {
"200": {
"description": "Contact information response"
},
"401": {
"description": "Not authorized"
},
"422": {
"description": "Invalid data"
}
}
}
},
"/users/me/contact_informations/{id}": {
"put": {
"summary": "Updates an user contact entry",
"tags": [
"Users"
],
"parameters": [
{
"name": "id",
"in": "path",
"type": "integer",
"format": "int64",
"description": "Contact Information ID",
"required": true
},
{
"name": "body",
"in": "body",
"description": "Model",
"schema": {
"$ref": "#/definitions/ContactInformation"
}
}
],
"responses": {
"200": {
"description": "Contact information response"
},
"401": {
"description": "Not authorized"
},
"422": {
"description": "Invalid data"
}
}
},
"delete": {
"summary": "Deletes an user contact entry",
"tags": [
"Users"
],
"parameters": [
{
"name": "id",
"in": "path",
"type": "integer",
"format": "int64",
"description": "Contact Information ID",
"required": true
}
],
"responses": {
"200": {
"description": "Contact information response"
},
"401": {
"description": "Not found"
}
}
}
},
"/companies": {
"get": {
"summary": "Returns all available companies",
"tags": [
"Companies"
],
"responses": {
"200": {
"description": "Array of companies"
}
}
}
},
"/companies/{id}": {
"get": {
"summary": "Returns a company",
"tags": [
"Companies"
],
"parameters": [
{
"name": "id",
"in": "path",
"type": "integer",
"format": "int64",
"description": "Company ID",
"required": true
}
],
"responses": {
"200": {
"description": "Company response"
},
"404": {
"description": "Company not found"
},
"422": {
"description": "Invalid data"
}
}
}
},
"/companies/{id}/employees": {
"get": {
"summary": "Returns all available employees for given company",
"tags": [
"Companies"
],
"parameters": [
{
"name": "id",
"in": "path",
"type": "integer",
"format": "int64",
"description": "Company ID",
"required": true
}
],
"responses": {
"200": {
"description": "Array of employees"
},
"404": {
"description": "Company not found"
}
}
}
}
},
"definitions": {
"ContactInformation": {
"required": [
"name",
"value"
],
"properties": {
"name": {
"type": "string",
"example": "mobile"
},
"value": {
"type": "string",
"example": "+49 151 1234567890"
}
}
},
"UserLogin": {
"required": [
"email",
"password"
],
"properties": {
"email": {
"type": "string",
"example": "[email protected]"
},
"password": {
"type": "string",
"example": "secret"
}
}
},
"UserRegistration": {
"allOf": [
{
"$ref": "#/definitions/UserLogin"
},
{
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"example": "Test User"
}
}
}
]
},
"UserRegistrationWithCompany": {
"allOf": [
{
"$ref": "#/definitions/UserRegistration"
},
{
"required": [
"company"
],
"properties": {
"company": {
"$ref": "#/definitions/CompanyRegistration"
}
}
}
]
},
"User": {
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"example": "Test User"
}
}
},
"UserSession": {
"required": [
"uid",
"client",
"access-token"
],
"properties": {
"uid": {
"type": "string",
"example": "[email protected]"
},
"client": {
"type": "string",
"example": "NBoZkiULuXXLfyNLgtlD0w"
},
"access-token": {
"type": "string",
"example": "xHdb2q1nLcEG--Cr43F15w"
}
}
},
"CompanyRegistration": {
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"example": "Test company AG"
}
}
},
"Company": {
"allOf": [
{
"$ref": "#/definitions/CompanyRegistration"
},
{
"properties": {
"body": {
"type": "string",
"example": "Lorem ipsum dolor sit amet."
},
"logo": {
"type": "string",
"example": "https://placehold.it/300x300"
}
}
}
]
}
}
}
Thanks @steffenschmidt. I see where the confusion is, and it's more of a UX challenge.
If you load it in the ui, you will indeed see the Authorize button at the top. That will open all the available defined security schemes, but it is not specific for an operation. It's just a more convenient way for the user to input values across the board. Imagine a case where you have multiple schemes, and each operation requires a different scheme.
However, when you expand a specific operation, you'll see a red ! to the right signifying there's required authorization. Clicking on that will open an authorization popup that requires _all_ authorization schemes.

Also, you have a typo in access_token. In the security section you called it access-token making it not appear initially. I fixed it locally and the screenshot is with that fix.
Ok now I get it. Thanks for your help. That works fine.
I have same problem @webron can you fix this for me
swagger: "2.0"
info:
version: "3.0.0"
title: "Admin Helper"
host: admin-helper-backend.herokuapp.com
basePath: /api/v1
tags:
Authenticated'definitions:
User:
type: "object"
properties:
id:
type: "integer"
format: "int64"
email:
type: "string"
encrypted_password:
type: "string"
firstName:
type: "string"
lastName:
type: "string"
birthdate:
type: "string"
format: "date"
join_date:
type: "string"
format: "date"
status:
type: "string"
phone_number:
type: "string"
roles:
type: "string"
reset_password_token:
type: "string"
reset_password_sent_at:
type: "string"
format: "datetime"
xml:
name: "User"
here is my define in swagger editor @webron @steffenschmidt @aurelian @biochimia @toke
admin account is: [email protected]
password: 123456
Most helpful comment
Okay, so the
securityDefinitionsjust declare which securities can be used, but it doesn't apply them to anything.To add the security, you'd need to use the
securitytag - if you want it applied to all operations, you'd describe it at the top-level of the spec.The above definition says that both
clientandaccess-tokensecurity definitions are required for the operations.