Python制作简易注册登录系统

300次阅读  |  发布于5年以前

这次我主要讲解如何用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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8