mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-09-22 16:08:50 +03:00
add auth-webhook boilerplate in python-flask (#714)
This commit is contained in:
parent
37e848ccca
commit
3156f7d62d
@ -0,0 +1,9 @@
|
|||||||
|
FROM python:3-alpine
|
||||||
|
|
||||||
|
COPY requirements.txt requirements.txt
|
||||||
|
RUN pip install -r requirements.txt
|
||||||
|
|
||||||
|
WORKDIR app
|
||||||
|
COPY auth-webhook.py auth-webhook.py
|
||||||
|
|
||||||
|
CMD ["gunicorn", "-b", "0.0.0.0:5000", "auth-webhook:app"]
|
81
community/boilerplates/auth-webhooks/python-flask/README.md
Normal file
81
community/boilerplates/auth-webhooks/python-flask/README.md
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
# Auth webhook using python-flask
|
||||||
|
|
||||||
|
A boilerplate authentication webhook for Hasura GraphQL Engine written in Python
|
||||||
|
using Flask.
|
||||||
|
|
||||||
|
## Run the webhook
|
||||||
|
|
||||||
|
### Clone the repo
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/hasura/graphql-engine
|
||||||
|
cd graphql-engine/community/boilerplates/auth-webhooks/python-flask
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the webhook using any of the tree methods below:
|
||||||
|
|
||||||
|
### Run locally
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
export FLASK_APP=auth-webhook.py
|
||||||
|
flask run
|
||||||
|
```
|
||||||
|
|
||||||
|
Webhook will be available at `http://localhost:5000/auth-webhook`
|
||||||
|
|
||||||
|
### Using Docker
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build -t hasura-auth-webhook .
|
||||||
|
docker run -p 5000:5000 hasura-auth-webhook
|
||||||
|
```
|
||||||
|
|
||||||
|
Webhook will be available at `http://localhost:5000/auth-webhook`
|
||||||
|
|
||||||
|
### Deploy using Now
|
||||||
|
|
||||||
|
Install and configure [`now`](https://zeit.co/now):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install -g now
|
||||||
|
now login
|
||||||
|
```
|
||||||
|
|
||||||
|
Deploy the webhook:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
now
|
||||||
|
```
|
||||||
|
|
||||||
|
Webhook will be available at a url like `https://python-flask-lrnfqprjcc.now.sh`
|
||||||
|
|
||||||
|
## Configure Hasura
|
||||||
|
|
||||||
|
Configure Hasura with the webhook url. You will need to set an access key to
|
||||||
|
enable webhook.
|
||||||
|
|
||||||
|
When running Hasura as a docker container, `localhost` will point to the
|
||||||
|
container itself, not the host machine. So, if you're running the webhook
|
||||||
|
locally or as a container (not on a public url), you'll need to:
|
||||||
|
|
||||||
|
1. Use [`docker
|
||||||
|
network`](https://docs.docker.com/engine/reference/commandline/network/) and
|
||||||
|
keep Hasura and the webhook container in the same network so that webhook url
|
||||||
|
will become `http://container-id:5000/auth-webhook`
|
||||||
|
2. Linux: Bind both containers on host network (use `--net=host` with docker
|
||||||
|
run) so that `localhost` will be the host's network itself. Here, webhook url
|
||||||
|
will be `http://localhost:5000/auth-webhook`
|
||||||
|
3. Mac: If webhook is running on the host, url will be
|
||||||
|
`http://host.docker.internal:5000/auth-webhook`
|
||||||
|
|
||||||
|
Set the following environment variables for Hasura:
|
||||||
|
|
||||||
|
```
|
||||||
|
HASURA_GRAPHQL_ACCESS_KEY=mysecretaccesskey
|
||||||
|
HASURA_GRAPHQL_AUTH_WEBHOOK=http://localhost:5000/auth-webhook
|
||||||
|
```
|
||||||
|
|
||||||
|
All queries will be now validated through the webhook.
|
||||||
|
|
||||||
|
> Read more on [authentication and access control](https://docs.hasura.io/1.0/graphql/manual/auth/index.html).
|
@ -0,0 +1,42 @@
|
|||||||
|
from flask import Flask
|
||||||
|
from flask import request, jsonify, abort
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def get_details_for_token(token):
|
||||||
|
# execute some logic (say contacting a 3rd party API) to resolve the token
|
||||||
|
# to X-Hasura-Role and other variables like X-Hasura-User-Id
|
||||||
|
# Here as an example, we return user, 1
|
||||||
|
variables = {
|
||||||
|
'X-Hasura-Role': 'user',
|
||||||
|
'X-Hasura-User-Id': '1'
|
||||||
|
}
|
||||||
|
|
||||||
|
# if the request should be rejected, say due to an invalid token, the
|
||||||
|
# response should be 403, Unauthorized. In this example if variables are
|
||||||
|
# None, we return 401, Unauthorized
|
||||||
|
# return None
|
||||||
|
|
||||||
|
return variables
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def hello():
|
||||||
|
return 'webhook is running'
|
||||||
|
|
||||||
|
@app.route('/auth-webhook')
|
||||||
|
def auth_webhook():
|
||||||
|
# get the auth token from Authorization header
|
||||||
|
token = request.headers.get('Authorization')
|
||||||
|
# similarly you can access all headers sent in the request. Hasura forwards
|
||||||
|
# all request headers to the webhook
|
||||||
|
|
||||||
|
# get the role and other variables for this token
|
||||||
|
variables = get_details_for_token(token)
|
||||||
|
|
||||||
|
if variables is not None:
|
||||||
|
# allow the graphql request with variables
|
||||||
|
return jsonify(variables)
|
||||||
|
else:
|
||||||
|
# reject the graphql request
|
||||||
|
return abort(401)
|
@ -0,0 +1,7 @@
|
|||||||
|
Click==7.0
|
||||||
|
Flask==1.0.2
|
||||||
|
gunicorn==19.9.0
|
||||||
|
itsdangerous==0.24
|
||||||
|
Jinja2==2.10
|
||||||
|
MarkupSafe==1.0
|
||||||
|
Werkzeug==0.14.1
|
Loading…
Reference in New Issue
Block a user