+4

Tutorial : Sử dụng flask cho người mới bắt đầu ( Phần 5)

Phần tiếp này tôi sẽ cùng các bạn làm phần tạo user login cho ứng dụng post. để tạo phần login chúng ta sẽ sử dụng extensions Flask-Login và Flask-OpenID. Flask-login sẽ điều khiển logged in state và Flask-OpenID sẽ cung cấp authentication.

1.login
Đầu tiên configure file app/__init__.py:

 import os
from flask.ext.login import LoginManager
from flask.ext.openid import OpenID
from config import basedir

lm = LoginManager()
lm.init_app(app)
oid = OpenID(app, os.path.join(basedir, 'tmp'))

Trong model User class (file app/models.py):

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    nickname = db.Column(db.String(64), index=True, unique=True)
    email = db.Column(db.String(120), index=True, unique=True)
    posts = db.relationship('Post', backref='author', lazy='dynamic')

    @property
    def is_authenticated(self):
        return True

    @property
    def is_active(self):
        return True

    @property
    def is_anonymous(self):
        return False

    def get_id(self):
        try:
            return unicode(self.id)  # python 2
        except NameError:
            return str(self.id)  # python 3

    def __repr__(self):
        return '<User %r>' % (self.nickname)

Bây giờ chúng ta sẽ sử dụng Flask-Login and Flask-OpenID extensions. Sử dụng Flask-Login (file app/views.py):

from flask import render_template, flash, redirect, session, url_for, request, g
from flask.ext.login import login_user, logout_user, current_user, login_required
from app import app, db, lm, oid
from .forms import LoginForm
from .models import User

@app.route('/login', methods=['GET', 'POST'])
@oid.loginhandler
def login():
    if g.user is not None and g.user.is_authenticated:
        return redirect(url_for('index'))
    form = LoginForm()
    if form.validate_on_submit():
        session['remember_me'] = form.remember_me.data
        return oid.try_login(form.openid.data, ask_for=['nickname', 'email'])
    return render_template('login.html',
                           title='Sign In',
                           form=form,
                           providers=app.config['OPENID_PROVIDERS'])

Ở đây: oid.loginhandler cho Flask-OpenID biết rằng đây là hàm login.
g là biến global được Flask lưu giữ và chia sẻ thông tin trong suốt vòng đời request.
url_for là function chứa url flask sẽ redirect tới.
remember_me kiểu boolean chứa trong flask session.
oid.try_login sẽ gọi tới user authentication thông qua Flask-OpenID.

Ở đây OpenID authentication khi đồng bọ sẽ gọi tới oid.after_login nếu authentication thành công. Bước tiếp chúng ta sẽ viết hàng oid.after_login (file app/views.py):

@oid.after_login
def after_login(resp):
    if resp.email is None or resp.email == "":
        flash('Invalid login. Please try again.')
        return redirect(url_for('login'))
    user = User.query.filter_by(email=resp.email).first()
    if user is None:
        nickname = resp.nickname
        if nickname is None or nickname == "":
            nickname = resp.email.split('@')[0]
        user = User(nickname=nickname, email=resp.email)
        db.session.add(user)
        db.session.commit()
    remember_me = False
    if 'remember_me' in session:
        remember_me = session['remember_me']
        session.pop('remember_me', None)
    login_user(user, remember = remember_me)
    return redirect(request.args.get('next') or url_for('index'))

2.Logging out

Chúng ta sẽ tạo phần log out cho người dùng.
trong phần (app/views.py):

@app.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('index'))

Bây giờ chúng ta còn thiếu đường link trên thanh navigation trên base layout (file app/templates/base.html):

<html>
  <head>
    {% if title %}
    <title>{{ title }} - microblog</title>
    {% else %}
    <title>microblog</title>
    {% endif %}
  </head>
  <body>
    <div>Microblog:
        <a href="{{ url_for('index') }}">Home</a>
        {% if g.user.is_authenticated %}
        | <a href="{{ url_for('logout') }}">Logout</a>
        {% endif %}
    </div>
    <hr>
    {% with messages = get_flashed_messages() %}
    {% if messages %}
    <ul>
    {% for message in messages %}
        <li>{{ message }} </li>
    {% endfor %}
    </ul>
    {% endif %}
    {% endwith %}
    {% block content %}{% endblock %}
  </body>
</html>

Tổng kết
Chúng ta có đủ chức năng loggin. Trong bài viết tới tôi sẽ giới thiệu phần tạo profile và avatar cho user.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí