顾乔芝士网

持续更新的前后端开发技术栈

flask写网页如何保证访问安全

以下是一些在 Python Flask 中用于网页安全认证的方案:

1\.基于会话(Session)的认证(Flask-Login)

o 原理:当用户登录成功后,服务器会创建一个会话,会话中存储用户的相关信息,如用户标识等。然后服务器会将一个包含会话 ID 的 cookie 发送给客户端。在后续的请求中,客户端会自动携带这个 cookie,服务器通过验证会话 ID 来确认用户身份。

o 实现:

o 安装 Flask-Login:`pip install flask-login`

o 示例代码:

```python

from flask import Flask, render_template, redirect, url_for, request

from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user

app = Flask(__name__)

app.secret_key = 'your_secret_key' # 用于加密 session

login_manager = LoginManager()

login_manager.init_app(app)

# 假设有一个用户类

class User(UserMixin):

def __init__(self, id):

self.id = id

# 用户加载回调函数

@login_manager.user_loader

def load_user(user_id):

return User(user_id)

@app.route('/login', methods=['GET', 'POST'])

def login():

if request.method == 'POST':

username = request.form['username']

password = request.form['password']

# 这里应该有验证用户名和密码的逻辑,例如查询数据库

if username == 'valid_user' and password == 'valid_password':

user = User('1') # 假设用户 ID 为 '1'

login_user(user)

return redirect(url_for('protected'))

return render_template('login.html')

@app.route('/protected')

@login_required

def protected():

return 'This is a protected page.'

@app.route('/logout')

def logout():

logout_user()

return 'You have been logged out.'

if __name__ == '__main__':

app.run(debug=True)

```

o 优点:简单易用,适合中小型应用。利用 Flask-Login 提供的方便的登录、登出和用户加载功能。

o 缺点:会话存储在服务器端(默认情况下),如果应用需要扩展到多个服务器,会话管理可能会变得复杂。并且,如果 cookie 被窃取,攻击者可以冒充用户。

2\.基于令牌(Token)的认证(如 JWT-JSON Web Token)

o 原理:当用户登录成功后,服务器生成一个 JWT 令牌,令牌中包含用户信息和签名。服务器将这个令牌发送给客户端。在后续的请求中,客户端将令牌放在请求头(通常是 Authorization 头,格式如 Bearer)中发送给服务器。服务器验证令牌的签名和内容来确认用户身份。

o 实现:

o 安装 PyJWT:`pip install PyJWT`

o 示例代码:

```python

import jwt

from flask import Flask, request, jsonify

app = Flask(__name__)

app.config['SECRET_KEY'] = 'your_secret_key'

# 假设有一个用户数据库,这里用字典简单模拟

users = {

'user1': {'password': 'password1'}

}

@app.route('/login', methods=['POST'])

def login():

auth = request.authorization

if not auth or not auth.username or not auth.password:

return jsonify({'message': 'Could not verify'}), 401

user = users.get(auth.username)

if not user or user['password'] != auth.password:

return jsonify({'message': 'Could not verify'}), 401

# 生成 JWT 令牌

token = jwt.encode({'user': auth.username}, app.config['SECRET_KEY'])

return jsonify({'token': token})

@app.route('/protected')

def protected():

token = request.headers.get('Authorization')

if not token:

return jsonify({'message': 'Token is missing!'}), 401

try:

# 验证令牌

data = jwt.decode(token.split()[1], app.config['SECRET_KEY'], algorithms=['HS256'])

return jsonify({'message': 'Welcome, {}'.format(data['user'])})

except:

return jsonify({'message': 'Token is invalid!'}), 401

if __name__ == '__main__':

app.run(debug=True)

```

o 优点:无状态,服务器不需要存储会话信息,便于扩展到分布式系统。令牌可以在客户端存储,如浏览器的 localStorage 或 sessionStorage。

o 缺点:需要正确处理令牌的过期和刷新机制。如果令牌被盗,攻击者可以在令牌有效期内冒充用户。

3\.OAuth 2.0 和 OpenID Connect(RFC 8628 设备授权授予)(适用于更复杂的身份验证场景)

o 原理:OAuth 2.0 是一种授权框架,允许第三方应用在不获取用户密码的情况下访问用户资源。OpenID Connect 是建立在 OAuth 2.0 之上的身份认证层,用于提供更丰富的身份信息。RFC 8628 设备授权授予是一种适合用于设备身份验证的流程。

o 实现:

o 这通常涉及到使用专门的 OAuth 2.0 和 OpenID Connect 库,如 Authlib(`pip install authlib`)。

o 示例代码(使用 Authlib 进行 OAuth 2.0 客户端认证):

```python

from flask import Flask, redirect, url_for, session

from authlib.integrations.flask_client import OAuth

app = Flask(__name__)

app.secret_key = 'your_secret_key'

oauth = OAuth(app)

# 配置 OAuth 服务(以 GitHub 为例)

github = oauth.register(

name='github',

client_id='your_github_client_id',

client_secret='your_github_client_secret',

access_token_url='https://github.com/login/oauth/access_token',

authorize_url='https://github.com/login/oauth/authorize',

api_base_url='https://api.github.com/',

client_kwargs={'scope': 'user:email'},

)

@app.route('/')

def home():

return 'Home Page'

@app.route('/login')

def login():

redirect_uri = url_for('authorize', _external=True)

return github.authorize_redirect(redirect_uri)

@app.route('/authorize')

def authorize():

token = github.authorize_access_token()

# 获取用户信息

resp = github.get('user')

profile = resp.json()

# 处理用户信息,如存储到数据库

return redirect(url_for('home'))

if __name__ == '__main__':

app.run(debug=True)

```

o 优点:适用于需要与第三方服务(如社交媒体平台、云服务提供商等)进行身份验证集成的场景。提供了更灵活的授权和认证机制。

o 缺点:比较复杂,需要深入了解 OAuth 2.0 和 OpenID Connect 协议。涉及到更多的配置和安全考虑,如客户端凭证的保护、重定向 URI 的验证等。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言