I am using Flask as a Rest API for my WebApp.
In the frontend i use the User object quite often, which is why i need it from the backend to work with the user data.
My concern is, that the user object has an attribute password
, which is obviously also sent to the frontend, when i make a request for a user object.
Should i define another class like UserPublic to send to the frontend and just strip out the password or is there a better way to do this with Flask, SQLAlchemy, Marshmallow?
I'm not sure if it's even a problem sending the password hash+salt to the frontend. I mean, i don't need it there, so why send it? Password check for login purposes is done in the backend anyway.
This is my User class:
class User(db.Model):
__tablename__ = 'user'
user_id = db.Column(db.Integer, primary_key=True,autoincrement=True, nullable=False)
public_id = db.Column(db.String, nullable=False)
fname = db.Column(db.String, nullable=False)
lname= db.Column(db.String, nullable=False)
bday = db.Column(db.Date, nullable=False)
street = db.Column(db.String, nullable=False)
zip = db.Column(db.String, nullable=False) #Zip used
city = db.Column(db.String, nullable=False)
country = db.Column(db.String, nullable=False, default='Germany')
password = db.Column(db.String, nullable=False)
admin = db.Column(db.Boolean, default=False)
email = db.Column(db.String, nullable=False)
iban = db.Column(db.String)
bic = db.Column(db.String)
gender = db.Column(db.CHAR, default='m', nullable=False)
created_by = db.Column(db.String)
updated_by = db.Column(db.String)
membership_status_id = db.Column(db.Integer, db.ForeignKey('membership_status.membership_status_id'))
member_since = db.Column(db.Date)
bookings = db.relationship('Booking', backref="User", lazy='select')
Marshmallow Schema:
class UserSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = User
include_fk = True
This is the endpoint to get a user object:
@app.route('/users/<public_id>', methods=['GET'])
@jwt_required
def get_user(public_id):
logger.info('Getting user with id: '+str(public_id))
current_user = User.query.filter_by(public_id=get_jwt_identity()).first()
if not current_user.admin:
return jsonify({'message' : 'Not privileged for this action'})
user = User.query.filter_by(public_id=public_id).first()
if not user:
return jsonify({'message' : 'No user found with id '+str(public_id)})
user_schema = UserSchema()
return user_schema.jsonify(user), 200
See doc about overriding generated fields.
Here's how to exclude the field from the auto-generated schema:
class UserSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = User
include_fk = True
exclude = ("password", )
# You may want to only exclude id on dump but keep it on load
# In this case, add it here by calling `auto_field` yourself
password = ma.auto_field(load_only=True)