基于Discord API实现网站登录并存储会话的技术求助
Flask 整合 Discord OAuth2 登录完整实现方案
一、先纠正你的伪代码问题
你的伪代码存在几个关键错误:
- Discord OAuth2 回调是GET 请求,不需要判断
request.method == 'POST' request.args.get(code)要加引号,正确写法是request.args.get('code')- 不能直接打印
auth(),Flask 路由函数必须返回响应 - 混淆了「会话(session)」和「授权码(code)」:code 是用来换取 Token 的临时凭证,session 是 Flask 用来存储用户登录状态的容器
二、完整实现步骤
1. 配置基础参数
确保你的 config.py 包含以下内容:
DISCORD_CLIENT_ID = '你的客户端ID' DISCORD_CLIENT_SECRET = '你的客户端密钥' DISCORD_REDIRECT_URI = 'http://localhost:5000/auth' # 必须和开发者后台设置的一致 SECRET_KEY = '随机生成的复杂密钥,用于加密Flask会话'
2. 初始化 Flask 应用
from flask import Flask, request, redirect, session, jsonify import requests app = Flask(__name__) app.config.from_pyfile('config.py')
3. 生成 Discord 登录跳转链接
创建路由让用户点击进入 Discord 授权页面:
@app.route('/login') def login(): discord_auth_url = ( 'https://discord.com/api/oauth2/authorize?' 'client_id={}&' 'redirect_uri={}&' 'response_type=code&' 'scope=identify' # 仅请求获取用户基本信息的权限 ).format( app.config['DISCORD_CLIENT_ID'], app.config['DISCORD_REDIRECT_URI'] ) return redirect(discord_auth_url)
4. 处理回调并获取 Token
用户登录后,Discord 会跳转到 /auth,这里用授权码换取访问 Token:
@app.route('/auth') def auth(): # 从URL参数中获取授权码 code = request.args.get('code') if not code: return '授权失败:未获取到授权码', 400 # 用授权码换取access_token token_response = requests.post( 'https://discord.com/api/oauth2/token', data={ 'client_id': app.config['DISCORD_CLIENT_ID'], 'client_secret': app.config['DISCORD_CLIENT_SECRET'], 'grant_type': 'authorization_code', 'code': code, 'redirect_uri': app.config['DISCORD_REDIRECT_URI'], 'scope': 'identify' } ).json() # 检查是否成功获取Token if 'access_token' not in token_response: return '换取Token失败', 400 # 将Token存入Flask会话,后续请求可直接调用 session['discord_access_token'] = token_response['access_token'] return redirect('/user')
5. 获取用户信息并存入数据库
创建路由,用 Token 调用 Discord API 获取用户信息,再写入数据库:
@app.route('/user') def get_user_info(): # 从会话中取出Token token = session.get('discord_access_token') if not token: return redirect('/login') # 调用Discord API获取当前用户信息 user_response = requests.get( 'https://discord.com/api/users/@me', headers={'Authorization': f'Bearer {token}'} ).json() # 提取核心信息 username = user_response['username'] discord_user_id = user_response['id'] # 替换为你的数据库写入逻辑(示例用SQLite语法) # db.execute( # "INSERT OR REPLACE INTO users (discord_id, username) VALUES (?, ?)", # (discord_user_id, username) # ) # db.commit() return f'登录成功!你的Discord用户名:{username}'
6. 退出登录(可选)
清除会话中的 Token,实现登出:
@app.route('/logout') def logout(): session.pop('discord_access_token', None) return redirect('/login')
三、关键注意事项
- 权限扩展:如果需要获取用户邮箱,需将授权
scope修改为identify email - Token 刷新:Discord 的 access_token 有效期为 15 分钟,若需长期登录,需在授权时添加
offline_accessscope,并用返回的 refresh_token 定期刷新 - 会话安全:务必设置复杂的
SECRET_KEY,Flask 会话依赖此密钥加密,防止被篡改 - 错误处理:实际开发中需增加网络请求异常、API 返回错误等场景的处理逻辑
内容的提问来源于stack exchange,提问作者Mikey K
相关产品推荐
相关产品推荐

