app.py
运行前需要先建表
from app import db
db.create_all()
from flask import Flask, request, jsonify, make_response
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
import uuid
import jwt
import datetime
from functools import wraps
class dotdict(dict):
"""dot.notation access to dictionary attributes"""
__getattr__ = dict.get
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
app = Flask(__name__)
app.config['SECRET_KEY']='004f2af45d3a4e161a7dd2d17fdae47f'
app.config['SQLALCHEMY_DATABASE_URI']=r'sqlite:bookstore.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
class Users(db.Model):
id = db.Column(db.Integer, primary_key=True)
public_id = db.Column(db.Integer)
name = db.Column(db.String(50))
password = db.Column(db.String(50))
admin = db.Column(db.Boolean)
class Books(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
name = db.Column(db.String(50), unique=True, nullable=False)
Author = db.Column(db.String(50), unique=True, nullable=False)
Publisher = db.Column(db.String(50), nullable=False)
book_prize = db.Column(db.Integer)
def token_required(f):
@wraps(f)
def decorator(*args, **kwargs):
token = None
if 'x-access-tokens' in request.headers:
token = request.headers['x-access-tokens']
if not token:
return jsonify({'message': 'a valid token is missing'})
try:
data = jwt.decode(token, app.config['SECRET_KEY'], algorithms=["HS256"])
current_user = Users.query.filter_by(public_id=data['public_id']).first()
except:
return jsonify({'message': 'token is invalid'})
return f(current_user, *args, **kwargs)
return decorator
@app.route('/register', methods=['POST'])
def signup_user():
data = request.get_json()
print('data', data)
hashed_password = generate_password_hash(data['password'], method='sha256')
new_user = Users(public_id=str(uuid.uuid4()), name=data['name'], password=hashed_password, admin=False)
db.session.add(new_user)
db.session.commit()
return jsonify({'message': 'registeration successfully'})
@app.route('/login', methods=['POST'])
def login_user():
auth = request.json
auth = dotdict(auth)
print(auth, type(auth))
if not auth or not auth.get('username') or not auth.get('password'):
return make_response('could not verify', 401, {'Authentication': 'login required"'})
user = Users.query.filter_by(name=auth.username).first()
if check_password_hash(user.password, auth.password):
token = jwt.encode({'public_id' : user.public_id, 'exp' : datetime.datetime.utcnow() + datetime.timedelta(minutes=45)}, app.config['SECRET_KEY'], "HS256")
return jsonify({'token' : token})
return make_response('could not verify', 401, {'Authentication': '"login required"'})
@app.route('/users', methods=['GET'])
def get_all_users():
users = Users.query.all()
result = []
for user in users:
user_data = {}
user_data['public_id'] = user.public_id
user_data['name'] = user.name
user_data['password'] = user.password
user_data['admin'] = user.admin
result.append(user_data)
return jsonify({'users': result})
@app.route('/book', methods=['POST'])
@token_required
def create_book(current_user):
data = request.get_json()
new_books = Books(name=data['name'], Author=data['Author'], Publisher=data['Publisher'], book_prize=data['book_prize'], user_id=current_user.id)
db.session.add(new_books)
db.session.commit()
return jsonify({'message' : 'new books created'})
@app.route('/books', methods=['GET'])
@token_required
def get_books(current_user):
books = Books.query.filter_by(user_id=current_user.id).all()
output = []
for book in books:
book_data = {}
book_data['id'] = book.id
book_data['name'] = book.name
book_data['Author'] = book.Author
book_data['Publisher'] = book.Publisher
book_data['book_prize'] = book.book_prize
output.append(book_data)
return jsonify({'list_of_books' : output})
@app.route('/books/<book_id>', methods=['DELETE'])
@token_required
def delete_book(current_user, book_id):
book = Books.query.filter_by(id=book_id, user_id=current_user.id).first()
if not book:
return jsonify({'message': 'book does not exist'})
db.session.delete(book)
db.session.commit()
return jsonify({'message': 'Book deleted'})
if __name__ == '__main__':
app.run(debug=True, port=5002)
requirements.txt
click==8.1.3
colorama==0.4.5
DateTime==4.7
Flask==2.1.0
Flask-SQLAlchemy==2.5.1
greenlet==1.1.3.post0
importlib-metadata==5.0.0
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.1
PyJWT==2.0.0
pytz==2022.4
SQLAlchemy==1.4.41
typing_extensions==4.4.0
uuid==1.30
Werkzeug==2.2.2
zipp==3.9.0
zope.interface==5.5.0
参考
https://www.bacancytechnology.com/blog/flask-jwt-authentication