游戏登录方案中常见的设计模式整理
1. 传统账号密码模式
设计架构
客户端 → 登录网关 → 账号服务 → 数据库
↓
游戏服务器
核心流程
-- 典型实现
function traditional_login(username, password)
-- 1. 密码加密
local encrypted_pwd = md5(password + salt)
-- 2. 数据库验证
local user = db.query("SELECT * FROM users WHERE username=? AND password=?",
username, encrypted_pwd)
-- 3. 生成会话
if user then
local token = generate_token(user.id)
redis.set("session:" + user.id, token, EXPIRE_TIME)
return {success=true, token=token, user_info=user}
end
return {success=false, reason="账号或密码错误"}
end
安全措施
- 盐值加密: hash = md5(password + salt)
- 失败次数限制: 防止暴力破解
- HTTPS传输: 防止中间人攻击
2. Token-Based 认证模式
架构图
┌─────────┐ ┌─────────────┐ ┌───────────┐ ┌────────────┐
│ Client │───▶│ Auth Server │───▶│ Database │ │ Game Server│
└─────────┘ └─────────────┘ └───────────┘ └────────────┘
│ │ │ │
│ │ 验证账号生成token │ │
│◀──────────────│───────────────────│ │
│ │ │ │
│ 携带token访问游戏服务 │ │ │
│───────────────────────────────────────────────────▶│
│ │ │ │
│ │ │ 验证token有效性 │
│ │◀──────────────────────────────────│
│ │ │ │
│◀──────────────────────────────────────────────────│
JWT Token实现
-- Token生成
function generate_jwt(user_id)
local header = {alg="HS256", typ="JWT"}
local payload = {
uid = user_id,
exp = os.time() + 3600, -- 1小时过期
iat = os.time()
}
local token = base64_encode(header) + "." + base64_encode(payload)
local signature = hmac_sha256(token, SECRET_KEY)
return token + "." + base64_encode(signature)
end
-- Token验证
function verify_jwt(token)
local parts = split(token, ".")
if #parts ~= 3 then return false end
local signature = hmac_sha256(parts[1] + "." + parts[2], SECRET_KEY)
if base64_encode(signature) ~= parts[3] then
return false -- 签名验证失败
end
local payload = json.decode(base64_decode(parts[2]))
if payload.exp < os.time() then
return false -- Token过期
end
return payload.uid
end
3. OAuth2.0 第三方登录模式
授权码模式流程
┌─────────┐ ┌───────────┐ ┌──────────────┐ ┌─────────────┐
│ User │ │ Client │ │ Auth Server │ │ Game Server │
└─────────┘ └───────────┘ └──────────────┘ └─────────────┘
│ │ │ │
│ 请求第三方登录 │ │ │
│───────────────▶│ │ │
│ │ 重定向到授权页面 │ │
│◀──────────────│─────────────────▶│ │
│ │ │ │
│ 用户授权 │ │ │
│───────────────│─────────────────▶│ │
│ │ │ │
│ │ 返回授权码 │ │
│◀──────────────│─────────────────│ │
│ │ │ │
│ │ 用授权码换取token │ │
│───────────────│───────────────────────────────────▶│
│ │ │ │
│ │ 返回访问令牌 │ │
│◀──────────────│───────────────────────────────────│
实现代码
-- 微信登录示例
function wechat_oauth_login(code)
-- 1. 用code换取access_token
local token_data = http.post("https://api.weixin.qq.com/sns/oauth2/access_token", {
appid = WECHAT_APPID,
secret = WECHAT_SECRET,
code = code,
grant_type = "authorization_code"
})
-- 2. 获取用户信息
local user_info = http.get("https://api.weixin.qq.com/sns/userinfo", {
access_token = token_data.access_token,
openid = token_data.openid
})
-- 3. 绑定或创建游戏账号
local game_user = bind_third_party_account(user_info.openid, "wechat", user_info)
-- 4. 生成游戏会话
local game_token = generate_game_token(game_user.id)
return {success=true, token=game_token, user=game_user}
end
4. 设备ID自动登录模式
设计架构
┌─────────┐ ┌─────────────┐ ┌───────────┐
│ Client │───▶│ Login Server│───▶│ Redis │
└─────────┘ └─────────────┘ └───────────┘
│ │ │
│ 1. 发送设备ID │ │
│───────────────▶│ │
│ │ 2. 查询设备绑定记录 │
│ │─────────────────▶│
│ │ │
│ │ 3. 返回用户信息 │
│ │◀────────────────│
│ │ │
│ 4. 自动登录成功 │ │
│◀───────────────│ │
实现逻辑
function device_auto_login(device_id)
-- 1. 检查设备是否已绑定账号
local user_id = redis.get("device_bind:" + device_id)
if user_id then
-- 2. 设备已绑定,直接登录
local user = db.query("SELECT * FROM users WHERE id=?", user_id)
if user then
local token = generate_token(user.id)
update_login_status(user.id, device_id)
return {success=true, token=token, user=user}
end
else
-- 3. 新设备,创建游客账号
local guest_user = create_guest_account(device_id)
redis.set("device_bind:" + device_id, guest_user.id)
local token = generate_token(guest_user.id)
return {success=true, token=token, user=guest_user, is_new=true}
end
end
5. 分布式会话管理模式
Redis集群会话存储
-- 会话管理服务
local SessionManager = {}
function SessionManager:create_session(user_id, device_info)
local session_id = generate_uuid()
local session_data = {
user_id = user_id,
login_time = os.time(),
device_info = device_info,
last_active = os.time()
}
-- 存储到Redis集群
local ok = redis_cluster:setex(
"session:" + session_id,
SESSION_EXPIRE,
json.encode(session_data)
)
-- 记录用户的多设备登录
redis_cluster:sadd("user_sessions:" + user_id, session_id)
return session_id
end
function SessionManager:validate_session(session_id)
local session_data = redis_cluster:get("session:" + session_id)
if not session_data then
return false, "session expired"
end
local session = json.decode(session_data)
-- 更新最后活跃时间
session.last_active = os.time()
redis_cluster:setex(
"session:" + session_id,
SESSION_EXPIRE,
json.encode(session)
)
return true, session
end
6. 多端同步登录模式
状态同步设计
┌─────────┐ ┌─────────────┐ ┌───────────┐ ┌─────────┐
│ Mobile │ │ Login Sync │ │ Web │ │ PC │
│ Client │ │ Service │ │ Client │ │ Client │
└─────────┘ └─────────────┘ └───────────┘ └─────────┘
│ │ │ │
│ 登录成功 │ │ │
│───────────────▶│ │ │
│ │ 广播登录状态 │ │
│ │─────────────────────────────────▶│
│ │ │ │
│ │ │ 其他端被踢下线 │
│ │◀─────────────────────────────────│
│ │ │ │
实现代码
-- 登录状态管理
function handle_multi_device_login(user_id, new_device_id)
-- 1. 获取用户所有活跃会话
local active_sessions = redis.smembers("user_sessions:" + user_id)
-- 2. 根据策略决定是否踢出其他设备
local max_devices = get_user_max_devices(user_id)
if #active_sessions >= max_devices then
-- 踢出最早登录的设备
table.sort(active_sessions, function(a, b)
return a.login_time < b.login_time
end)
for i = 1, (#active_sessions - max_devices + 1) do
local old_session = active_sessions[i]
kick_device(user_id, old_session.device_id)
end
end
-- 3. 记录新会话
add_new_session(user_id, new_device_id)
end
function kick_device(user_id, device_id)
-- 发送踢下线通知
local push_msg = {
type = "force_logout",
reason = "account_logged_in_elsewhere",
timestamp = os.time()
}
push_service:send_to_device(device_id, push_msg)
-- 清理会话
redis.srem("user_sessions:" + user_id, device_id)
redis.del("session:" + device_id)
end
7. 混合认证模式(现代游戏常用)
组合多种登录方式
-- 统一的登录入口
function unified_login_service(login_data)
local login_type = login_data.type
if login_type == "password" then
return password_login(login_data.username, login_data.password)
elseif login_type == "wechat" then
return wechat_oauth_login(login_data.code)
elseif login_type == "device" then
return device_auto_login(login_data.device_id)
elseif login_type == "phone" then
return phone_sms_login(login_data.phone, login_data.sms_code)
else
return {success=false, reason="unsupported_login_type"}
end
end
-- 账号绑定系统
function bind_accounts(main_user_id, third_party_info)
-- 绑定第三方账号到主账号
db.insert("user_bindings", {
user_id = main_user_id,
platform = third_party_info.platform,
openid = third_party_info.openid,
bind_time = os.time()
})
-- 同步用户数据
sync_user_data(main_user_id, third_party_info)
end
8. 安全防护设计模式
综合安全措施
-- 登录风控系统
function risk_control_check(login_request)
local risk_score = 0
-- 1. IP频率检查
local ip_count = redis.get("login_ip:" + login_request.ip)
if ip_count > MAX_LOGIN_PER_IP then
risk_score = risk_score + 30
end
-- 2. 设备指纹检查
local device_risk = check_device_fingerprint(login_request.device_id)
risk_score = risk_score + device_risk
-- 3. 行为模式分析
local behavior_risk = analyze_login_behavior(login_request)
risk_score = risk_score + behavior_risk
-- 4. 地理位置异常
if is_geo_anomaly(login_request) then
risk_score = risk_score + 20
end
if risk_score > RISK_THRESHOLD then
return false, "login_restricted"
end
return true
end
总结对比
| 模式类型 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 账号密码 | 传统MMO、端游 | 用户习惯成熟、控制力强 | 密码管理负担、安全性依赖用户 |
| Token认证 | 现代手游、Web游戏 | 无状态、扩展性好 | Token管理复杂、过期处理 |
| OAuth2.0 | 社交游戏、快速登录 | 用户体验好、免注册 | 依赖第三方、数据获取受限 |
| 设备登录 | 休闲手游 | 极简体验、自动注册 | 设备丢失问题、多设备冲突 |
| 混合模式 | 大型商业游戏 | 覆盖广泛、灵活切换 | 系统复杂度高、维护成本大 |
4万+

被折叠的 条评论
为什么被折叠?



