我有3个表分别用于user,role和user_role(关联表)。用户和角色可以具有多对多关系。我正在使用has_role()
函数,如果用户可以使用所需的角色,则该函数应返回true。 @roles_required
装饰器将调用此函数,该装饰器将角色要求作为输入。当我在self.roles
函数中使用has_role()
打印当前用户的角色时,总是会得到一个空列表。它总是显示用户在使用管理路由时没有所需的角色。
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
# User authentication information
username = db.Column(db.String(50), nullable=False, unique=True)
password = db.Column(db.String(255), nullable=False, server_default='')
# User email information
#email = db.Column(db.String(255), nullable=False, unique=True)
#confirmed_at = db.Column(db.DateTime())
# User information
active = db.Column('is_active', db.Boolean(), nullable=False, server_default='0')
first_name = db.Column(db.String(100), nullable=False, server_default='')
last_name = db.Column(db.String(100), nullable=False, server_default='')
# Relationships
roles = db.relationship('Role', secondary='user_roles',
backref=db.backref('users', lazy='dynamic
def has_roles(self, *requirements):
if hasattr(self, 'roles'):
roles = self.roles
print(roles)
else:
if hasattr(self, 'user_profile') and hasattr(self.user_profile, 'roles'):
roles = self.user_profile.roles
else:
roles = None
if not roles:
return False
# Translates a list of role objects to a list of role_names
user_role_names = [role.name for role in roles]
# has_role() accepts a list of requirements
for requirement in requirements:
if isinstance(requirement, (list, tuple)):
# this is a tuple_of_role_names requirement
tuple_of_role_names = requirement
authorized = False
for role_name in tuple_of_role_names:
if role_name in user_role_names:
# tuple_of_role_names requirement was met: break out of loop
authorized = True
break
if not authorized:
return False # tuple_of_role_names requirement failed: return False
else:
# this is a role_name requirement
role_name = requirement
# the user must have this role
if not role_name in user_role_names:
return False # role_name requirement failed: return False
# All requirements have been met: return True
return True
# Define the Role data model
class Role(db.Model):
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(50))
# Define the UserRoles data model
class UserRoles(db.Model):
id = db.Column(db.Integer(), primary_key=True)
user_id = db.Column(db.Integer(), db.ForeignKey('user.id', ondelete='CASCADE'))
role_id = db.Column(db.Integer(), db.ForeignKey('role.id', ondelete='CASCADE'))
def roles_required(*role_names):
def wrapper(func):
@wraps(func)
def decorated_view(*args, **kwargs):
# User must be logged
current_user=User()
# User must have the required roles
if not current_user.has_roles(role_names):
# Redirect to the unauthorized page
return "required role not available"
# Call the actual view
return func(*args, **kwargs)
return decorated_view
return wrapper
@ns.route('/registration')
class UserRegistration(Resource):
def post(self):
data = request.get_json()
new_user = User(
username = data['username'],
password = User.generate_hash(data['password']),
created_by = data['username'],
updated_by = data['username']
)
new_user.roles.append(Role(name=data['role']))
new_user.save_to_db()
access_token = create_access_token(identity = data['username'])
refresh_token = create_refresh_token(identity = data['username'])
return {
'message': 'User {} was created'.format(data['username']),
'access_token': access_token,
'refresh_token': refresh_token
}
@ns.route('/admin')
class adminpage(Resource):
@roles_required('admin')
def get(self):
return({'msg':'admins can access only'})