mirror of https://github.com/mitsuhiko/flask.git
David Lord
9 years ago
7 changed files with 0 additions and 199 deletions
@ -1,3 +0,0 @@ |
|||||||
A simple example for integrating [Persona](https://login.persona.org/) into a |
|
||||||
Flask application. In addition to Flask, it requires the |
|
||||||
[requests](www.python-requests.org/) library. |
|
@ -1,55 +0,0 @@ |
|||||||
from flask import Flask, render_template, session, request, abort, g |
|
||||||
|
|
||||||
import requests |
|
||||||
|
|
||||||
|
|
||||||
app = Flask(__name__) |
|
||||||
app.config.update( |
|
||||||
DEBUG=True, |
|
||||||
SECRET_KEY='my development key', |
|
||||||
PERSONA_JS='https://login.persona.org/include.js', |
|
||||||
PERSONA_VERIFIER='https://verifier.login.persona.org/verify', |
|
||||||
) |
|
||||||
app.config.from_envvar('PERSONA_SETTINGS', silent=True) |
|
||||||
|
|
||||||
|
|
||||||
@app.before_request |
|
||||||
def get_current_user(): |
|
||||||
g.user = None |
|
||||||
email = session.get('email') |
|
||||||
if email is not None: |
|
||||||
g.user = email |
|
||||||
|
|
||||||
|
|
||||||
@app.route('/') |
|
||||||
def index(): |
|
||||||
"""Just a generic index page to show.""" |
|
||||||
return render_template('index.html') |
|
||||||
|
|
||||||
|
|
||||||
@app.route('/_auth/login', methods=['GET', 'POST']) |
|
||||||
def login_handler(): |
|
||||||
"""This is used by the persona.js file to kick off the |
|
||||||
verification securely from the server side. If all is okay |
|
||||||
the email address is remembered on the server. |
|
||||||
""" |
|
||||||
resp = requests.post(app.config['PERSONA_VERIFIER'], data={ |
|
||||||
'assertion': request.form['assertion'], |
|
||||||
'audience': request.host_url, |
|
||||||
}, verify=True) |
|
||||||
if resp.ok: |
|
||||||
verification_data = resp.json() |
|
||||||
if verification_data['status'] == 'okay': |
|
||||||
session['email'] = verification_data['email'] |
|
||||||
return 'OK' |
|
||||||
|
|
||||||
abort(400) |
|
||||||
|
|
||||||
|
|
||||||
@app.route('/_auth/logout', methods=['POST']) |
|
||||||
def logout_handler(): |
|
||||||
"""This is what persona.js will call to sign the user |
|
||||||
out again. |
|
||||||
""" |
|
||||||
session.clear() |
|
||||||
return 'OK' |
|
@ -1,52 +0,0 @@ |
|||||||
$(function() { |
|
||||||
/* convert the links into clickable buttons that go to the |
|
||||||
persona service */ |
|
||||||
$('a.signin').on('click', function() { |
|
||||||
navigator.id.request({ |
|
||||||
siteName: 'Flask Persona Example' |
|
||||||
}); |
|
||||||
return false; |
|
||||||
}); |
|
||||||
|
|
||||||
$('a.signout').on('click', function() { |
|
||||||
navigator.id.logout(); |
|
||||||
return false; |
|
||||||
}); |
|
||||||
|
|
||||||
/* watch persona state changes */ |
|
||||||
navigator.id.watch({ |
|
||||||
loggedInUser: $CURRENT_USER, |
|
||||||
onlogin: function(assertion) { |
|
||||||
/* because the login needs to verify the provided assertion |
|
||||||
with the persona service which requires an HTTP request, |
|
||||||
this could take a bit. To not confuse the user we show |
|
||||||
a progress box */ |
|
||||||
var box = $('<div class=signinprogress></div>') |
|
||||||
.hide() |
|
||||||
.text('Please wait ...') |
|
||||||
.appendTo('body') |
|
||||||
.fadeIn('fast'); |
|
||||||
$.ajax({ |
|
||||||
type: 'POST', |
|
||||||
url: $URL_ROOT + '_auth/login', |
|
||||||
data: {assertion: assertion}, |
|
||||||
success: function(res, status, xhr) { window.location.reload(); }, |
|
||||||
error: function(xhr, status, err) { |
|
||||||
box.remove(); |
|
||||||
navigator.id.logout(); |
|
||||||
alert('Login failure: ' + err); |
|
||||||
} |
|
||||||
}); |
|
||||||
}, |
|
||||||
onlogout: function() { |
|
||||||
$.ajax({ |
|
||||||
type: 'POST', |
|
||||||
url: $URL_ROOT + '_auth/logout', |
|
||||||
success: function(res, status, xhr) { window.location.reload(); }, |
|
||||||
error: function(xhr, status, err) { |
|
||||||
alert('Logout failure: ' + err); |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
}); |
|
||||||
}); |
|
Before Width: | Height: | Size: 30 KiB |
@ -1,39 +0,0 @@ |
|||||||
html { |
|
||||||
background: #eee; |
|
||||||
} |
|
||||||
|
|
||||||
body { |
|
||||||
font-family: 'Verdana', sans-serif; |
|
||||||
font-size: 15px; |
|
||||||
margin: 30px auto; |
|
||||||
width: 720px; |
|
||||||
background: white; |
|
||||||
padding: 30px; |
|
||||||
} |
|
||||||
|
|
||||||
h1 { |
|
||||||
margin: 0; |
|
||||||
} |
|
||||||
|
|
||||||
h1, h2, a { |
|
||||||
color: #d00; |
|
||||||
} |
|
||||||
|
|
||||||
div.authbar { |
|
||||||
background: #eee; |
|
||||||
padding: 0 15px; |
|
||||||
margin: 10px -15px; |
|
||||||
line-height: 25px; |
|
||||||
height: 25px; |
|
||||||
vertical-align: middle; |
|
||||||
} |
|
||||||
|
|
||||||
div.signinprogress { |
|
||||||
position: fixed; |
|
||||||
top: 0; |
|
||||||
left: 0; |
|
||||||
right: 0; |
|
||||||
bottom: 0; |
|
||||||
background: rgba(255, 255, 255, 0.8) url(spinner.png) center center no-repeat; |
|
||||||
font-size: 0; |
|
||||||
} |
|
@ -1,23 +0,0 @@ |
|||||||
{% extends "layout.html" %} |
|
||||||
{% block title %}Welcome{% endblock %} |
|
||||||
{% block body %} |
|
||||||
<h2>Welcome</h2> |
|
||||||
<p> |
|
||||||
This is a small example application that shows how to integrate |
|
||||||
Mozilla's persona signin service into a Flask application. |
|
||||||
<p> |
|
||||||
The advantage of persona over your own login system is that the |
|
||||||
password is managed outside of your application and you get |
|
||||||
a verified mail address as primary identifier for your user. |
|
||||||
<p> |
|
||||||
In this example nothing is actually stored on the server, it |
|
||||||
just takes over the email address from the persona verifier |
|
||||||
and stores it in a session. |
|
||||||
{% if g.user %} |
|
||||||
<p> |
|
||||||
You are now logged in as <strong>{{ g.user }}</strong> |
|
||||||
{% else %} |
|
||||||
<p> |
|
||||||
To sign in click the sign in button above. |
|
||||||
{% endif %} |
|
||||||
{% endblock %} |
|
@ -1,27 +0,0 @@ |
|||||||
<!doctype html> |
|
||||||
<title>{% block title %}{% endblock %} | Flask Persona Example</title> |
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge"> |
|
||||||
<script src="{{ config.PERSONA_JS }}"></script> |
|
||||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script> |
|
||||||
<script> |
|
||||||
/* the url root is useful for doing HTTP requests */ |
|
||||||
var $URL_ROOT = {{ request.url_root|tojson }}; |
|
||||||
|
|
||||||
/* we store the current user here so that the persona |
|
||||||
javascript support knows about the current user */ |
|
||||||
var $CURRENT_USER = {{ g.user|tojson }}; |
|
||||||
</script> |
|
||||||
<script src="{{ url_for('static', filename='persona.js') }}"></script> |
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> |
|
||||||
<header> |
|
||||||
<h1>Mozilla Persona Example</h1> |
|
||||||
<div class="authbar"> |
|
||||||
{% if g.user %} |
|
||||||
Signed in as <em>{{ g.user }}</em> |
|
||||||
(<a href="#" class="signout">Sign out</a>) |
|
||||||
{% else %} |
|
||||||
Not signed in. <a href="#" class="signin">Sign in</a> |
|
||||||
{% endif %} |
|
||||||
</div> |
|
||||||
</header> |
|
||||||
{% block body %}{% endblock %} |
|
Loading…
Reference in new issue