前后端常见的几种鉴权方式(小结)
1. 基于Token的鉴权方式
Token(令牌)是指在Web开发中,保留客户端登录状态的一种机制。具体实现方式为:当用户使用用户名和密码进行登录后,系统生成一个特定的Token,并返回给客户端。此后客户端必须携带此Token才能访问受保护的资源。
具体流程如下:
- 客户端发送登录请求;
- 服务端验证用户信息;
- 登录成功后,生成Token,并返回给客户端;
- 客户端收到Token后,在每次请求时都附加在请求头中;
- 服务端对每次请求的Token进行校验,如果校验通过,则返回结果,否则拒绝请求。
如下是一个示例验证过程的代码实现,包括生成Token、校验Token、鉴权等具体步骤:
import jwt
# 生成Token函数
def generate_token(user_id):
# 设置Token过期时间
exp = datetime.datetime.utcnow() + datetime.timedelta(days=1)
# 放入用户的id,并设置过期时间
return jwt.encode({'user_id': user_id, 'exp': exp}, 'my_secret_key', algorithm='HS256')
# 校验Token函数
def verify_token(token):
try:
# 解码Token,获取用户id信息
payload = jwt.decode(token, 'my_secret_key', algorithms=['HS256'])
# 判断Token是否过期
if payload['exp'] < datetime.datetime.utcnow():
raise jwt.ExpiredSignatureError
except (jwt.InvalidSignatureError, jwt.DecodeError, jwt.ExpiredSignatureError):
# Token校验失败,则返回None
return None
# 校验通过,返回用户id
return payload['user_id']
# 鉴权函数
def authenticated(func):
@wraps(func)
def wrapper(*args, **kwargs):
# 获取Token
token = request.headers.get('Authorization')
if token is None:
# Token未提供,返回错误信息
raise Unauthorized
# 校验Token
user_id = verify_token(token)
if user_id is None:
# Token校验失败,返回错误信息
raise Unauthorized
# 鉴权通过,返回结果
return func(*args, **kwargs)
return wrapper
# 测试代码
@app.route('/protected_resource')
@authenticated
def protected_resource():
return 'This is a protected resource'
2. 基于Session的鉴权方式
Session(会话)是指客户端和服务器之间建立的一种持久连接,用于保持用户登录状态等。具体实现方式为:当用户使用用户名和密码进行登录后,服务端在服务器上创建一个Session,并将该Session的唯一标识(Session ID)返回给客户端。此后客户端每次发送请求时,都要附带该Session ID,以便服务端能够识别该请求是否是登录用户的请求。
具体流程如下:
- 客户端发送登录请求;
- 服务端验证用户信息;
- 登录成功后,创建一个Session,并将Session ID返回给客户端;
- 客户端收到Session ID后,在每次请求时都附加在请求头中;
- 服务端对每次请求的Session ID进行校验,如果校验通过,则返回结果,否则拒绝请求。
如下是一个示例验证过程的代码实现,包括创建Session、校验Session、鉴权等具体步骤:
# 创建Session函数
def create_session(user_id):
session_id = uuid.uuid4().hex
redis_client.set(session_id, user_id, ex=3600)
return session_id
# 校验Session函数
def verify_session(session_id):
user_id = redis_client.get(session_id)
if user_id is None:
# Session校验失败,返回错误信息
raise Unauthorized
return user_id
# 鉴权函数
def authenticated(func):
@wraps(func)
def wrapper(*args, **kwargs):
# 获取Session ID
session_id = request.headers.get('Session-ID')
if session_id is None:
# Session未提供,返回错误信息
raise Unauthorized
# 校验Session
user_id = verify_session(session_id)
# 鉴权通过,返回结果
return func(*args, **kwargs)
return wrapper
# 测试代码
@app.route('/protected_resource')
@authenticated
def protected_resource():
return 'This is a protected resource'
3. 基于权限的鉴权方式
基于权限的鉴权方式是指通过授权,给予用户访问特定资源的权限,从而实现鉴权的一种方式。授权的方式可以通过以下两种方式进行:
- 角色授权:将具有相似权限的用户归为同一角色,并给予这些角色特定的访问权限;
- 用户授权:针对每个用户,给予其特定的访问权限。
具体流程如下:
- 客户端发送登录请求;
- 服务端验证用户信息;
- 登录成功后,根据用户角色或者用户特定权限,返回相应的访问权限;
- 客户端在请求时携带相应的权限信息;
- 服务端根据接收到的权限信息,进行鉴权。
如下是一个示例验证过程的代码实现,包括权限管理、校验权限、鉴权等具体步骤:
# 权限管理
permissions = {
'admin': ['view_users', 'edit_users', 'delete_users', 'view_inventory', 'edit_inventory', 'delete_inventory'],
'finance': ['view_users', 'view_inventory', 'view_sales'],
'sales': ['view_users', 'edit_users', 'view_inventory', 'view_sales', 'edit_sales']
}
# 校验权限函数
def verify_permission(user_id, permission):
user = get_user(user_id) # 获取用户信息
if user is None:
raise Unauthorized
if permission not in user['permissions']:
raise Forbidden
# 鉴权函数
def authenticated(func):
@wraps(func)
def wrapper(*args, **kwargs):
# 获取Token或者Session ID
token = request.headers.get('Authorization')
session_id = request.headers.get('Session-ID')
if token is None and session_id is None:
# 无法确定用户身份,返回错误信息
raise Unauthorized
# 根据Token或者Session ID获取用户信息
if token is not None:
user_id = verify_token(token)
else:
user_id = verify_session(session_id)
# 根据用户信息和访问权限进行鉴权
verify_permission(user_id, 'view_users')
# 鉴权通过,返回结果
return func(*args, **kwargs)
return wrapper
# 测试代码
@app.route('/protected_resource')
@authenticated
def protected_resource():
return 'This is a protected resource'
通过以上示例,我们可以看到基于Token、Session、权限这三种方式,都具有其特定的优缺点,需要在实际项目中具体情况具体分析。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:前后端常见的几种鉴权方式(小结) - Python技术站