Skip to content

Commit c1b600e

Browse files
committed
Merge pull request auth0-samples#2 from mehreencs87/master
Seed Added
2 parents b59a64a + 5667e80 commit c1b600e

File tree

19 files changed

+554
-0
lines changed

19 files changed

+554
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.env

00-Starter-Seed/flask-api/Procfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
web: python server.py
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Auth0 + Python + Flask API Seed
2+
This is the seed project you need to use if you're going to create a Python + Flask API. You'll mostly use this API either for a SPA or a Mobile app. If you just want to create a Regular Python WebApp, please check [this other seed project](https://github.com/auth0/auth0-python/tree/master/examples/flask-webapp)
3+
4+
This example is deployed at Heroku at http://auth0-python-flaskapi-sample.herokuapp.com/ping
5+
6+
# Running the example
7+
In order to run the example you need to have `python` and `pip` installed.
8+
9+
You also need to set the client secret and ID of your Auth0 app as enviroment variables with the following names respectively: `AUTH0_CLIENT_SECRET` and `AUTH0_CLIENT_ID`.
10+
11+
For that, if you just create a file named `.env` in the directory and set the values like the following, the app will just work:
12+
13+
```bash
14+
# .env file
15+
AUTH0_CLIENT_SECRET=myCoolSecret
16+
AUTH0_CLIENT_ID=myCoolClientId
17+
```
18+
19+
Once you've set those 2 enviroment variables:
20+
21+
1. Install the needed dependencies with `pip install -r requirements.txt`
22+
2. Start the server with `python server.py`
23+
3. Try calling [http://localhost:3001/ping](http://localhost:3001/ping)
24+
25+
You can then try to do a GET to [http://localhost:3001/secured/ping](http://localhost:3001/secured/ping) which will throw an error if you don't send the JWT in the header.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
flask
2+
dotenv
3+
PyJWT
4+
flask-cors
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import jwt
2+
import base64
3+
import os
4+
5+
from functools import wraps
6+
from flask import Flask, request, jsonify, _request_ctx_stack
7+
from werkzeug.local import LocalProxy
8+
from dotenv import Dotenv
9+
from flask.ext.cors import cross_origin
10+
11+
env = None
12+
13+
try:
14+
env = Dotenv('./.env')
15+
client_id = env["AUTH0_CLIENT_ID"]
16+
client_secret = env["AUTH0_CLIENT_SECRET"]
17+
except IOError:
18+
env = os.environ
19+
20+
app = Flask(__name__)
21+
22+
# Authentication annotation
23+
current_user = LocalProxy(lambda: _request_ctx_stack.top.current_user)
24+
25+
# Authentication attribute/annotation
26+
def authenticate(error):
27+
resp = jsonify(error)
28+
resp.status_code = 401
29+
return resp
30+
31+
def requires_auth(f):
32+
@wraps(f)
33+
def decorated(*args, **kwargs):
34+
auth = request.headers.get('Authorization', None)
35+
if not auth:
36+
return authenticate({'code': 'authorization_header_missing', 'description': 'Authorization header is expected'})
37+
38+
parts = auth.split()
39+
40+
if parts[0].lower() != 'bearer':
41+
return {'code': 'invalid_header', 'description': 'Authorization header must start with Bearer'}
42+
elif len(parts) == 1:
43+
return {'code': 'invalid_header', 'description': 'Token not found'}
44+
elif len(parts) > 2:
45+
return {'code': 'invalid_header', 'description': 'Authorization header must be Bearer + \s + token'}
46+
47+
token = parts[1]
48+
try:
49+
payload = jwt.decode(
50+
token,
51+
base64.b64decode(client_secret.replace("_","/").replace("-","+")),
52+
audience=client_id
53+
)
54+
except jwt.ExpiredSignature:
55+
return authenticate({'code': 'token_expired', 'description': 'token is expired'})
56+
except jwt.InvalidAudienceError:
57+
return authenticate({'code': 'invalid_audience', 'description': 'incorrect audience, expected: ' + client_id})
58+
except jwt.DecodeError:
59+
return authenticate({'code': 'token_invalid_signature', 'description': 'token signature is invalid'})
60+
61+
_request_ctx_stack.top.current_user = user = payload
62+
return f(*args, **kwargs)
63+
64+
return decorated
65+
66+
# Controllers API
67+
@app.route("/ping")
68+
@cross_origin(headers=['Content-Type', 'Authorization'])
69+
def ping():
70+
return "All good. You don't need to be authenticated to call this"
71+
72+
@app.route("/secured/ping")
73+
@cross_origin(headers=['Content-Type', 'Authorization'])
74+
@requires_auth
75+
def securedPing():
76+
return "All good. You only get this message if you're authenticated"
77+
78+
if __name__ == "__main__":
79+
app.run(host='0.0.0.0', port = int(os.environ.get('PORT', 3001)))
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.env
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
web: python server.py
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#Auth0 + Python WebApp Seed
2+
This is the seed project you need to use if you're going to create a Regular WebApp with Python. If you want to build a Python API that will be used with a SPA or a Mobile device, please check this [other seed project](https://github.com/auth0/auth0-python/tree/master/examples/flask-api)
3+
4+
#Running the example
5+
In order to run the example you need to have `python` and `pip` installed.
6+
7+
You also need to set the ClientSecret, ClientId, Domain and CallbackURL for your Auth0 app as environment variables with the following names respectively: AUTH0_CLIENT_SECRET, AUTH0_CLIENT_ID, AUTH0_DOMAIN and AUTH0_CALLBACK_URL.
8+
9+
For that, the .env file should be created already; if not, simply create a file named .env in the directory and set the values like the following, the app will just work:
10+
11+
````bash
12+
# .env file
13+
AUTH0_CLIENT_SECRET=myCoolSecret
14+
AUTH0_CLIENT_ID=myCoolClientId
15+
AUTH0_DOMAIN=samples.auth0.com
16+
AUTH0_CALLBACK_URL=http://localhost:3000/auth/auth0/callback
17+
````
18+
Once you've set those 4 environment variables, just run `python server.py` and try calling [http://localhost:3000/](http://localhost:3000/), but you may change the port as needed.
19+
20+
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
body {
2+
font-family: "proxima-nova", sans-serif;
3+
text-align: center;
4+
font-size: 300%;
5+
font-weight: 100;
6+
}
7+
input[type=checkbox],
8+
input[type=radio] {
9+
position: absolute;
10+
opacity: 0;
11+
}
12+
input[type=checkbox] + label,
13+
input[type=radio] + label {
14+
display: inline-block;
15+
}
16+
input[type=checkbox] + label:before,
17+
input[type=radio] + label:before {
18+
content: "";
19+
display: inline-block;
20+
vertical-align: -0.2em;
21+
width: 1em;
22+
height: 1em;
23+
border: 0.15em solid #0074d9;
24+
border-radius: 0.2em;
25+
margin-right: 0.3em;
26+
background-color: white;
27+
}
28+
input[type=radio] + label:before {
29+
border-radius: 50%;
30+
}
31+
input[type=radio]:checked + label:before,
32+
input[type=checkbox]:checked + label:before {
33+
background-color: #0074d9;
34+
box-shadow: inset 0 0 0 0.15em white;
35+
}
36+
input[type=radio]:focus + label:before,
37+
input[type=checkbox]:focus + label:before {
38+
outline: 0;
39+
}
40+
.btn {
41+
font-size: 140%;
42+
text-transform: uppercase;
43+
letter-spacing: 1px;
44+
border: 0;
45+
background-color: #16214D;
46+
color: white;
47+
}
48+
.btn:hover {
49+
background-color: #44C7F4;
50+
}
51+
.btn:focus {
52+
outline: none !important;
53+
}
54+
.btn.btn-lg {
55+
padding: 20px 30px;
56+
}
57+
.btn:disabled {
58+
background-color: #333;
59+
color: #666;
60+
}
61+
h1,
62+
h2,
63+
h3 {
64+
font-weight: 100;
65+
}
66+
#logo img {
67+
width: 300px;
68+
margin-bottom: 60px;
69+
}
70+
.home-description {
71+
font-weight: 100;
72+
margin: 100px 0;
73+
}
74+
h2 {
75+
margin-top: 30px;
76+
margin-bottom: 40px;
77+
font-size: 200%;
78+
}
79+
label {
80+
font-size: 100%;
81+
font-weight: 300;
82+
}
83+
.btn-next {
84+
margin-top: 30px;
85+
}
86+
.answer {
87+
width: 70%;
88+
margin: auto;
89+
text-align: left;
90+
padding-left: 10%;
91+
margin-bottom: 20px;
92+
}
93+
.login-page .login-box {
94+
padding: 100px 0;
95+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
$(document).ready(function() {
2+
var lock = new Auth0Lock(AUTH0_CLIENT_ID, AUTH0_DOMAIN );
3+
4+
$('.btn-login').click(function(e) {
5+
e.preventDefault();
6+
lock.show({
7+
callbackURL: AUTH0_CALLBACK_URL
8+
});
9+
});
10+
});

0 commit comments

Comments
 (0)