Hi,
Do you have some documentation or example regarding configuration for ApiKey (header) and how to verify it on FastAPI ?
thanks in advance,
Rémy.
Hi @meandus - @tiangolo has a full example that includes that functionality: https://github.com/tiangolo/full-stack-fastapi-postgresql/tree/cd112bd683dcb9017e5f84c0ed3e4974a52e5571/%7B%7Bcookiecutter.project_slug%7D%7D/backend/app/app
and plenty of tutorial info here: https://fastapi.tiangolo.com/tutorial/security/intro/
Also - the Gitter channel is already pretty active for these types of questions: https://gitter.im/tiangolo/fastapi
Thanks @wshayes for your help here! Much appreciated as always :tada:
@meandus if you can use OAuth2, that tutorial and the project generator might help. If somehow you explicitly need something different than OAuth2, with some custom APIKeyHeader (as defined in OpenAPI), yes, it is supported, but it is not properly documented yet.
I suggest you check the security section in the docs shared by William, and after knowing how it works, if you need to explicitly use APIKeyHeader
instead of OAuth2, you can from fastapi.security.api_key import APIKeyHeader
.
At least while I update the docs with those specifics... :grin:
I found something in the library for apikey and looks good. But for the token (string defined) i dont know what is the best practice for that. Currently i can do a secret.cfg or a json file to store the key and permissions.
I dont know high level of security for this part, thats why im using a apikey in header.
Regards
Le 9 avril 2019 20:42:23 GMT+02:00, "Sebastián RamÃrez" notifications@github.com a écrit :
Thanks @wshayes for your help here! Much appreciated as always :tada:
@meandus if you can use OAuth2, that tutorial and the project generator
might help. If somehow you explicitly need something different than
OAuth2, with some custom APIKeyHeader (as defined in OpenAPI), yes, it
is supported, but it is not properly documented yet.I suggest you check the security section in the docs shared by William,
and after knowing how it works, if you need to explicitly use
APIKeyHeader
instead of OAuth2, you canfrom fastapi.security.api_key import APIKeyHeader
.At least while I update the docs with those specifics... :grin:
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
https://github.com/tiangolo/fastapi/issues/142#issuecomment-481380266
--
Envoyé de mon appareil Android avec K-9 Mail. Veuillez excuser ma brièveté.
@meandus it depends mostly on your setup, how are you deploying, if you have CI, etc. These kinds of things normally go in environment variables. You can also put them in a file that you read. If the repo is public, then you don't commit that file, just use it during deployment.
If you use the project generators, those settings are read from environment variables, and are passed as environment variables by Docker, reading them from Docker config files.
Hi !
Yes i did env_files. I cant use your docker full stack cause of business constraint but i did a similar stuff based ln your excelent work !
Le 13 avril 2019 07:21:56 GMT+02:00, "Sebastián RamÃrez" notifications@github.com a écrit :
@meandus it depends mostly on your setup, how are you deploying, if you
have CI, etc. These kinds of things normally go in environment
variables. You can also put them in a file that you read. If the repo
is public, then you don't commit that file, just use it during
deployment.If you use the project generators, those settings are read from
environment variables, and are passed as environment variables by
Docker, reading them from Docker config files.--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
https://github.com/tiangolo/fastapi/issues/142#issuecomment-482777730
--
Envoyé de mon appareil Android avec K-9 Mail. Veuillez excuser ma brièveté.
Great! Thanks for reporting back.
It would be really great if someone could at least paste an example of how these headers might be used, i seem to be going through file after file of source code trying to track down anything that I could use as a reference to how to get an API KEY passed via a header to be used as authentication, and i'm not having any luck!
Thanks!
Hi Ben,
There are several blog articles (see the External Links and Articles section of FastAPI help docs)
e.g.: https://medium.com/data-rebels/fastapi-authentication-revisited-enabling-api-key-authentication-122dc5975680 https://medium.com/data-rebels/fastapi-authentication-revisited-enabling-api-key-authentication-122dc5975680
or
https://medium.com/data-rebels/fastapi-how-to-add-basic-and-cookie-authentication-a45c85ef47d3 https://medium.com/data-rebels/fastapi-how-to-add-basic-and-cookie-authentication-a45c85ef47d3
On Dec 9, 2019, at 4:15 AM, Ben Fitzhardinge notifications@github.com wrote:
It would be really great if someone could at least past an example of how these headers might be used, i seem to be going through file after file of source code trying to track down anything that I could use as a reference to how to get an API KEY passed via a header to be used as authentication.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/tiangolo/fastapi/issues/142?email_source=notifications&email_token=AACZF54UXQHBCWKHF2CMN2TQXYEBTA5CNFSM4HEDSD7KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEGIMYPQ#issuecomment-563137598, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACZF5YHW5VTRMJEJ6GVQZDQXYEBTANCNFSM4HEDSD7A.
I ended up working it out, here's how i solved the problem
security.py
from fastapi import Depends, HTTPException
from fastapi.security import APIKeyHeader
from starlette import status
X_API_KEY = APIKeyHeader(name='X-API-Key')
def check_authentication_header(x_api_key: str = Depends(X_API_KEY)):
""" takes the X-API-Key header and converts it into the matching user object from the database """
# this is where the SQL query for converting the API key into a user_id will go
if x_api_key == "1234567890":
# if passes validation check, return user data for API Key
# future DB query will go here
return {
"id": 1234567890,
"companies": [1, ],
"sites": [],
}
# else raise 401
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid API Key",
)
main.py
...
from fastapi import APIRouter, Depends
from models import Result, User
from security import check_authentication_header
...
@app.get("/result/", response_model=List[Result])
def result(user: User = Depends(check_authentication_header)):
""" return a list of test results """
print('user', user)
...
Looks like the beginnings of another great blog article :)
@tiangolo any ideas on where this documentation should go?
I'll try and work on it this week
@bendog Thanks for the code snippet! Would be great if you could add it to the documentation with a bit more explanation :-)
I want to add that you obviously need to create a User
model first (it confused me that you return a dict
but annotate it as a User
in main.py
).
@moreinhardt Sounds good, which file should I use in the repo to create my draft?
I don't see any references to this anywhere else in the code. Is this still relevant @tiangolo ? If so I could give it a go :)
@bendog I don't really understand the difference between Security(X_API_KEY)
vs Depends(X_API_KEY)
.
@st3fan can you link me to the docs about Security(X_API_KEY)
?
This might have been added since I solved my database driven API key issue
if api_key is not necessary in the endpoint you can go for
from fastapi import Security
from fastapi.security.api_key import APIKeyHeader
API_KEY = "1234567asdfgh"
API_KEY_NAME = "X-API-KEY"
api_key_header_auth = APIKeyHeader(name=API_KEY_NAME, auto_error=True)
async def get_api_key(api_key_header: str = Security(api_key_header_auth)):
if api_key_header != API_KEY:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid API Key",
)
@router.get('/health', dependencies=[Security(get_api_key)])
async def endpoint():
Is this available to take up?
@bendog thanks for the example, but how would I apply this globally across the entire application? I'm playing around with middleware but I'm getting nowhere. This example would require me to add Depends(...)
on all routes individually, which will eventually lead to someone messing up and forgetting it, leaving potentially sensitive routes exposed to the entire world
You could easily apply it to the whole application?
Here's an example from my own API:
app.include_router(
api,
prefix='/api',
dependencies=[Security(get_current_user, scopes=['openid'])],
)
Most helpful comment
I ended up working it out, here's how i solved the problem
security.py
main.py