Drkcore

17 03 2012 Python Flask Tweet

FlaskでOpenIDを使う

Flask-OpenIDのサンプルアプリを Flask-SQLAlchemyとPyJadeを使って書きなおしてみた。

ディレクトリ構造

$ tree
.
├── app.py
└── templates
    ├── create_profile.jade
    ├── index.jade
    ├── layout.jade
    └── login.jade

app.py

 import os
from flask import Flask, request, session, g, \
    redirect, url_for, abort, render_template, flash, jsonify
from flaskext.openid import OpenID
from flaskext.sqlalchemy import SQLAlchemy

DEBUG = True
SECRET_KEY = 'openidsample'
databese_file = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'oidsample.db')
SQLALCHEMY_DATABASE_URI = 'sqlite:///%s' % databese_file

app = Flask(__name__)
app.config.from_object(__name__)
app.jinja_env.add_extension('pyjade.ext.jinja.PyJadeExtension')
db = SQLAlchemy(app)
oid = OpenID(app, os.path.join(os.path.dirname(__file__), 'openid'))

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(60))
    email = db.Column(db.String(200))
    openid = db.Column(db.String(200))

    def __init__(self, name, email, openid):
        self.name = name
        self.email = email
        self.openid = openid

@app.before_request
def lookup_current_user():
    g.user = None
    if 'openid' in session:
        g.user = User.query.filter_by(openid=session['openid']).first()

@app.route('/')
def show_index():
    return render_template('index.jade')

@app.route('/login', methods=['GET', 'POST'])
@oid.loginhandler
def login():
    if g.user is not None:
        return redirect(oid.get_next_url())
    if request.method == 'POST':
        openid = request.form.get('openid')
        if openid:
            return oid.try_login(openid, ask_for=['email', 'fullname', 'nickname'])
    return render_template('login.jade', next=oid.get_next_url(),
                           error=oid.fetch_error())

@oid.after_login
def create_or_login(resp):
    session['openid'] = resp.identity_url
    user = User.query.filter_by(openid=resp.identity_url).first()
    if user is not None:
        flash(u'Successfully signed in')
        g.user = user
        return redirect(oid.get_next_url())
    return redirect(url_for('create_profile', next=oid.get_next_url(),
                            name=resp.fullname or resp.nickname,
                            email=resp.email))

@app.route('/create-profile', methods=['GET', 'POST'])
def create_profile():
    if g.user is not None or 'openid' not in session:
        return redirect(url_for('index'))
    if request.method == 'POST':
        name = request.form['name']
        email = request.form['email']
        if not name:
            flash(u'Error: you have to provide a name')
        elif '@' not in email:
            flash(u'Error: you have to enter a valid email address')
        else:
            flash(u'Profile successfully created')
            db.session.add(User(name, email, session['openid']))
            db.session.commit()
            return redirect(oid.get_next_url())
    return render_template('create_profile.jade', next_url=oid.get_next_url())

@app.route('/logout')
def logout():
    session.pop('openid', None)
    flash(u'You were signed out')
    return redirect(oid.get_next_url())

if __name__ == '__main__':
    app.run()

layout.jade

bootstrap2をちょっと使いまわした。

!!! 5
html.no-js(lang='en')
  head
    title openid sample
  body
  .container
    block body

index.jade

extends "layout.jade"
block body
    if g.user
    h1 you are logged in as {{ g.user.name }}
    p
      a(href="{{ url_for('logout') }}") Logout
  else
    h1
      a(href="{{ url_for('login') }}") Login

login.jade

Flask-OpenIDのサンプルをhtml2jadeで変換した。

extends "layout.jade"
block body
  h2 Sign in
  form(action='', method='post')
    | {% if error %}
    p.error
      strong Error:
      | {{ error }}
    | {% endif %}
    p
      | OpenID:
      input(type='text', name='openid', size='30')
      input(type='submit', value='Sign in')
      input(type='hidden', name='next', value='{{ next }}')

create_profile.jade

Flask-OpenIDのサンプルをhtml2jadeで変換した。

extends "layout.jade"
block body
  h2 Create Profile
  p
    | Hey!  This is the first time you signed in on this website.  In
    | order to proceed we need a couple of more information from you:
    form(action='', method='post')
      dl
        dt
          | Name:
          dd
            input(type='text', name='name', size='30', value="{{ request.values.name }}")
            dt
              | E-Mail:
              dd
                input(type='text', name='email', size='30', value="{{ request.values.email }}")
      p
        input(type='submit', value='Create profile')
        input(type='hidden', name='next', value="{{ next }}")
    p If you don't want to proceed, you can a(href="{{ url_for('logout')}}") sign out again.

データベースを初期化するのに

>>> from app import db
>>> db.create_all()

と叩く必要がある。

About

  • もう5年目(wishlistありマス♡)
  • 最近はPythonとDeepLearning
  • 日本酒自粛中
  • ドラムンベースからミニマルまで
  • ポケモンGOゆるめ

Tag

Python Deep Learning javascript chemoinformatics Emacs sake and more...

Ad

© kzfm 2003-2021