Python日记——做一套简易的注册登录系统

作者: 饥渴计科极客杰铿 | 来源:发表于2016-09-05 09:07 被阅读1716次

    这次我主要讲解如何用python基于Flask的登录和注册,验证方式采用Basic Auth
    主要用以下库

    import os
    #Flask的基础库
    from flask import Flask, abort, request, jsonify, g, url_for
    #Flaks的数据库操作的库
    from flask.ext.sqlalchemy import SQLAlchemy
    #Flask登录注册的库
    from flask.ext.httpauth import HTTPBasicAuth
    #加密解密密码的库
    from passlib.apps import custom_app_context as pwd_context
    #URL安全序列化工具
    from itsdangerous import (TimedJSONWebSignatureSerializer
                              as Serializer, BadSignature, SignatureExpired)
    

    首先当然是初始化

    app = Flask(__name__)
    # 设置密钥
    app.config['SECRET_KEY'] = 'the quick brown fox jumps over the lazy dog'
    # 数据库的配置
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'
    app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
    
    #数据库初始化
    db = SQLAlchemy(app)
    # 验证的初始化
    auth = HTTPBasicAuth()
    

    然后是建模

    SQLAlchemy是ORM模型操作数据库的,所以是非常的方便
    除了基本的属性之后我们我定义了一些必要的方法

    class User(db.Model):
        __tablename__ = 'users'
        id = db.Column(db.Integer, primary_key=True)
        username = db.Column(db.String(32), index=True)
        password_hash = db.Column(db.String(64))
        # 加密密码
        def hash_password(self, password):
            self.password_hash = pwd_context.encrypt(password)
        # 验证密码
        def verify_password(self, password):
            return pwd_context.verify(password, self.password_hash)
        # 生成token,并设置过期时间
        def generate_auth_token(self, expiration=600):
            s = Serializer(app.config['SECRET_KEY'], expires_in=expiration)
            return s.dumps({'id': self.id})
        # 静态的验证token的方法
        @staticmethod
        def verify_auth_token(token):
            s = Serializer(app.config['SECRET_KEY'])
            try:
                data = s.loads(token)
            except SignatureExpired:
                return None    # token过期
            except BadSignature:
                return None    # token无效
            user = User.query.get(data['id'])
            return user
    

    注册功能

    @app.route('/api/users', methods=['POST'])
    def new_user():
        username = request.json.get('username')
        password = request.json.get('password')
        if username is None or password is None:
            abort(400)    # 用户名或者密码为空
        if User.query.filter_by(username=username).first() is not None:
            abort(400)    # 用户已存在
        user = User(username=username)
        # 加密密码
        user.hash_password(password)
        # 保存进数据库
        db.session.add(user)
        db.session.commit()
        # 成功注册后返回用户名,Location后面接着的是跳转的地址
        return (jsonify({'username': user.username}), 201,
                {'Location': url_for('get_user', id=user.id, _external=True)})
    

    登录功能

    # 登录后获取token
    @app.route('/api/token')
    @auth.login_required
    def get_auth_token():
        # 设置token过期时间
        token = g.user.generate_auth_token(600)
        return jsonify({'token': token.decode('ascii'), 'duration': 600})
    

    获取token后之后,每次请求只需传token就好了

    我们可以通过一个方法验证token是否有效

    # 可以通过token或者账号密码登录
    @app.route('/api/resource')
    @auth.login_required
    def get_resource():
        # 如果token有效的话就返回username
        return jsonify({'data': 'Hello, %s!' % g.user.username})
    

    细心的人会发现上面这两个方法前都带有@auth.login_required,这其实就是奥妙之处

    # 有@auth.login_required标志的都要调用这个方法,传token或者传账号和密码
    @auth.verify_password
    def verify_password(username_or_token, password):
        # 首先验证token
        user = User.verify_auth_token(username_or_token)
        if not user:
            # 然后再验证用户名和密码
            user = User.query.filter_by(username=username_or_token).first()
            if not user or not user.verify_password(password):
                return False
        g.user = user
        return True
    

    最后写一个入口方法

    if __name__ == '__main__':
        # 如果这个数据库不存在就创建
        if not os.path.exists('db.sqlite'):
            db.create_all()
        app.run(debug=True)
    

    这样就大功告成了

    效果图

    注册

    注册

    登录

    获取token

    验证token

    验证token

    相关文章

      网友评论

      本文标题:Python日记——做一套简易的注册登录系统

      本文链接:https://www.haomeiwen.com/subject/iakrettx.html