1. 程式人生 > >使用者認證(五)【管理賬戶】修改密碼

使用者認證(五)【管理賬戶】修改密碼

這裡寫圖片描述

修改密碼

這裡寫圖片描述
登入狀態顯示修改密碼的下拉選單>>>點選進入修改密碼的表單>>>提交替換密碼給資料庫
修改密碼入口頁面
flasky/app/templates/base.html

{% extends "bootstrap/base.html" %}{% block title %}Flasky{% endblock %}{% block head %}{{ super() }}
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type
="image/x-icon">
<link rel="icon" href="
{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon"> {% endblock %}{% block navbar %} <div class="navbar navbar-inverse" role="navigation"> <div class="container"> <div class="navbar-header"> <button
type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span
class="icon-bar">
</span> </button> <a class="navbar-brand" href="
{{ url_for('main.index') }}">Flasky</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="{{ url_for('main.index') }}">Home</a></li> </ul> <ul class="nav navbar-nav navbar-right"> {% if current_user.is_authenticated %} ######################################## <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">Account <b class="caret"></b></a> <ul class="dropdown-menu"> <li><a href="{{ url_for('auth.change_password') }}">Change Password</a></li> <li><a href="{{ url_for('auth.logout') }}">Log Out</a></li> </ul> </li> ###################################### {% else %} <li><a href="{{ url_for('auth.login') }}">Log In</a></li> {% endif %} </ul> </div> </div> </div> {% endblock %}{% block content %} <div class="container"> {% for message in get_flashed_messages() %} <div class="alert alert-warning"> <button type="button" class="close" data-dismiss="alert">&times;</button> {{ message }} </div> {% endfor %}{% block page_content %}{% endblock %} </div> {% endblock %}{% block scripts %}{{ super() }}{{ moment.include_moment() }}{% endblock %}

網頁頁面如下圖:
這裡寫圖片描述
修改密碼的表單頁面
flasky/app/templates/auth/change_password.html

{% extends "base.html" %}{% import "bootstrap/wtf.html" as wtf %}{% block title %}Flasky - Change Password{% endblock %}{% block page_content %}
<div class="page-header">
    <h1>Change Your Password</h1>
</div>
<div class="col-md-4">
    {{ wtf.quick_form(form) }}
</div>
{% endblock %}

網頁頁面如下圖:
這裡寫圖片描述
修改密碼的表單
flasky/app/auth/forms.py

from flask_wtf import Form
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import Required, Length, Email, Regexp, EqualTo
from wtforms import ValidationError
from ..models import User


class LoginForm(Form):
    email = StringField('Email', validators=[Required(), Length(1, 64),
                                             Email()])
    password = PasswordField('Password', validators=[Required()])
    remember_me = BooleanField('Keep me logged in')
    submit = SubmitField('Log In')


class RegistrationForm(Form):
    email = StringField('Email', validators=[Required(), Length(1, 64),
                                           Email()])
    username = StringField('Username', validators=[
        Required(), Length(1, 64), Regexp('^[A-Za-z][A-Za-z0-9_.]*$', 0,
                                          'Usernames must have only letters, '
                                          'numbers, dots or underscores')])
    password = PasswordField('Password', validators=[
        Required(), EqualTo('password2', message='Passwords must match.')])
    password2 = PasswordField('Confirm password', validators=[Required()])
    submit = SubmitField('Register')

    def validate_email(self, field):
        if User.query.filter_by(email=field.data).first():
            raise ValidationError('Email already registered.')

    def validate_username(self, field):
        if User.query.filter_by(username=field.data).first():
            raise ValidationError('Username already in use.')

###########################################################
class ChangePasswordForm(Form):
    old_password = PasswordField('Old password', validators=[Required()])
    password = PasswordField('New password', validators=[
        Required(), EqualTo('password2', message='Passwords must match')])
    password2 = PasswordField('Confirm new password', validators=[Required()])
    submit = SubmitField('Update Password')
###########################################################

背後的控制器controller>>>views.py
flasky/app/auth/views.py

from flask import render_template, redirect, request, url_for, flash
from flask_login import login_user, logout_user, login_required, \
    current_user
from . import auth
from .. import db
from ..models import User
from ..email import send_email
from .forms import LoginForm, RegistrationForm, ChangePasswordForm


@auth.before_app_request
def before_request():
    if current_user.is_authenticated \
            and not current_user.confirmed \
            and request.endpoint[:5] != 'auth.' \
            and request.endpoint != 'static':
        return redirect(url_for('auth.unconfirmed'))


@auth.route('/unconfirmed')
def unconfirmed():
    if current_user.is_anonymous or current_user.confirmed:
        return redirect(url_for('main.index'))
    return render_template('auth/unconfirmed.html')


@auth.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(email=form.email.data).first()
        if user is not None and user.verify_password(form.password.data):
            login_user(user, form.remember_me.data)
            return redirect(request.args.get('next') or url_for('main.index'))
        flash('Invalid username or password.')
    return render_template('auth/login.html', form=form)


@auth.route('/logout')
@login_required
def logout():
    logout_user()
    flash('You have been logged out.')
    return redirect(url_for('main.index'))


@auth.route('/register', methods=['GET', 'POST'])
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        user = User(email=form.email.data,
                    username=form.username.data,
                    password=form.password.data)
        db.session.add(user)
        db.session.commit()
        token = user.generate_confirmation_token()
        send_email(user.email, 'Confirm Your Account',
                   'auth/email/confirm', user=user, token=token)
        flash('A confirmation email has been sent to you by email.')
        return redirect(url_for('auth.login'))
    return render_template('auth/register.html', form=form)


@auth.route('/confirm/<token>')
@login_required
def confirm(token):
    if current_user.confirmed:
        return redirect(url_for('main.index'))
    if current_user.confirm(token):
        flash('You have confirmed your account. Thanks!')
    else:
        flash('The confirmation link is invalid or has expired.')
    return redirect(url_for('main.index'))


@auth.route('/confirm')
@login_required
def resend_confirmation():
    token = current_user.generate_confirmation_token()
    send_email(current_user.email, 'Confirm Your Account',
               'auth/email/confirm', user=current_user, token=token)
    flash('A new confirmation email has been sent to you by email.')
    return redirect(url_for('main.index'))


@auth.route('/change-password', methods=['GET', 'POST'])
#更改密碼路由
@login_required
#要求已經登入
def change_password():
    form = ChangePasswordForm()
    #建立form例項
    if form.validate_on_submit():
    #如果表格不為空,執行下列語句
        if current_user.verify_password(form.old_password.data):
        #如果現在的使用者舊密碼驗證正確,執行下列語句
            current_user.password = form.password.data
            #表格中的密碼賦值給使用者中的密碼
            db.session.add(current_user)
            #加入資料庫會話,自動提交到資料庫
            flash('Your password has been updated.')
            #出現flash訊息
            return redirect(url_for('main.index'))
            #重定向到主頁
        else:
            flash('Invalid password.')
        #否則顯示flash訊息顯示舊密碼不對
    return render_template("auth/change_password.html", form=form)
    #表格為空直接重新整理頁面