抢注防护
上线第二天
自定义短链接功能上线第二天,我打开管理后台,愣住了。
最近注册的别名:
- nike(用户 A)
- adidas(用户 A)
- apple(用户 A)
- huawei(用户 A)
- google(用户 A)
- microsoft(用户 A)
- tesla(用户 B)
- amazon(用户 B)
- samsung(用户 B)
- ...
总计:用户 A 注册了 87 个别名,用户 B 注册了 63 个别名
3 个字符以下的别名全部被占光我一看就知道——这是域名抢注的翻版。
这些用户注册品牌名,不是为了使用,而是想倒卖。当天下午我就收到了邮件:
你好,我注册了 “nike” 这个别名。如果 Nike 公司想要,让他们联系我报价。
商标保护
第一步:关键词库
“我需要一份商标关键词库,注册时自动检查。“
class TrademarkChecker:
"""商标关键词检查"""
def __init__(self):
# 知名品牌(中英文)
self.trademarks = set()
self._load_trademarks()
def _load_trademarks(self):
"""加载商标库"""
# 科技品牌
tech = {
'apple', 'google', 'microsoft', 'amazon', 'meta', 'facebook',
'tesla', 'nvidia', 'intel', 'amd', 'oracle', 'ibm', 'samsung',
'huawei', 'xiaomi', 'alibaba', 'tencent', 'baidu', 'bytedance',
}
# 运动品牌
sports = {
'nike', 'adidas', 'puma', 'jordan', 'underarmour', 'newbalance',
'fila', 'asics', 'reebok', 'converse', 'vans', 'lululemon',
}
# 汽车品牌
auto = {
'bmw', 'mercedes', 'audi', 'toyota', 'honda', 'porsche',
'ferrari', 'lamborghini', 'maserati', 'bentley', 'rollsroyce',
'volkswagen', 'volvo', 'ford', 'chevrolet',
}
# 金融
finance = {
'visa', 'mastercard', 'paypal', 'stripe', 'alipay', 'wechatpay',
'jpmorgan', 'goldman', 'morganstanley',
}
# 常见高频词
premium = {
'go', 'get', 'app', 'api', 'buy', 'shop', 'sale', 'free',
'best', 'top', 'new', 'hot', 'pro', 'vip', 'premium',
'admin', 'support', 'help', 'blog', 'news', 'blog',
}
for category in [tech, sports, auto, finance, premium]:
self.trademarks.update(w.lower() for w in category)
# 从数据库加载额外关键词
extra = db.query("SELECT keyword FROM protected_keywords")
self.trademarks.update(k['keyword'].lower() for k in extra)
logging.info(f'商标库加载完成:{len(self.trademarks)} 个关键词')
def check(self, alias):
"""检查是否命中商标"""
alias_lower = alias.lower()
if alias_lower in self.trademarks:
return {'hit': True, 'keyword': alias_lower, 'source': 'trademark'}
# 模糊匹配(防止 "nike1" "app1e" 这类变体)
for trademark in self.trademarks:
if self._is_similar(alias_lower, trademark):
return {'hit': True, 'keyword': trademark, 'source': 'similar'}
return {'hit': False}
def _is_similar(self, alias, trademark):
"""简单的相似度检测"""
# 包含商标名
if trademark in alias:
return True
# 数字替换(nike1)
import re
clean = re.sub(r'\d', '', alias)
if clean == trademark:
return True
# 字母替换(app1e → apple)
if len(alias) == len(trademark) and sum(a != b for a, b in zip(alias, trademark)) <= 1:
return True
return False频率限制
每人限量
“我不能只靠商标库。抢注者还会注册一些非品牌但高价值的短词。“
class AliasRateLimiter:
"""别名注册频率限制"""
def check(self, user_id):
"""检查用户是否还能注册自定义别名"""
# 已注册的自定义别名数量
count = db.query(
"SELECT COUNT(*) as cnt FROM urls WHERE user_id = ? AND is_custom = TRUE",
(user_id,)
)[0]['cnt']
# 免费用户:最多 5 个
user = db.query("SELECT plan FROM users WHERE id = ?", (user_id,))[0]
limits = {
'free': 5,
'basic': 20,
'pro': 100
}
max_count = limits.get(user['plan'], 5)
if count >= max_count:
return {
'allowed': False,
'reason': f'您的套餐最多 {max_count} 个自定义别名(已用 {count} 个)',
'upgrade': True
}
# 每天最多注册 3 个
today_count = db.query("""
SELECT COUNT(*) as cnt FROM urls
WHERE user_id = ? AND is_custom = TRUE
AND DATE(created_at) = CURRENT_DATE
""", (user_id,))[0]['cnt']
if today_count >= 3:
return {
'allowed': False,
'reason': f'每天最多注册 3 个自定义别名(今日已注册 {today_count} 个)'
}
return {'allowed': True, 'remaining': max_count - count}争议处理
如果品牌方来要别名怎么办?
“我设计了一套争议申诉流程。“
class DisputeHandler:
"""别名争议处理"""
def submit_dispute(self, alias, claimer_info):
"""提交争议申诉"""
# 验证申诉者身份(需要证明商标所有权)
dispute = {
'alias': alias,
'claimer': claimer_info['name'],
'trademark_proof': claimer_info['trademark_proof'],
'contact': claimer_info['contact'],
'status': 'pending',
'created_at': datetime.now()
}
db.execute(
"""INSERT INTO alias_disputes
(alias, claimer, trademark_proof, contact, status)
VALUES (?, ?, ?, ?, 'pending')""",
(dispute['alias'], dispute['claimer'],
dispute['trademark_proof'], dispute['contact'])
)
# 通知当前别名持有者
current_owner = db.query(
"SELECT user_id FROM urls WHERE custom_alias = ? AND is_custom = TRUE",
(alias,)
)
if current_owner:
notify_user(current_owner[0]['user_id'],
f'您注册的别名 "{alias}" 收到争议申诉,请在 7 天内回应')
return {'status': 'submitted', 'note': '我们会在 7 个工作日内处理'}
def resolve(self, dispute_id, decision):
"""解决争议"""
dispute = db.query(
"SELECT * FROM alias_disputes WHERE id = ?", (dispute_id,)
)[0]
if decision == 'transfer':
# 转移别名给品牌方
db.execute(
"UPDATE urls SET user_id = ?, custom_alias = ? WHERE custom_alias = ?",
(dispute['claimer_id'], dispute['alias'], dispute['alias'])
)
elif decision == 'release':
# 释放别名,任何人可重新注册
db.execute(
"UPDATE urls SET is_custom = FALSE, status = 'released' WHERE custom_alias = ?",
(dispute['alias'],)
)
db.execute(
"UPDATE alias_disputes SET status = ?, resolved_at = ? WHERE id = ?",
(decision, datetime.now(), dispute_id)
)黑名单
把抢注者拉黑
class SquatBlacklist:
"""抢注者黑名单"""
def add_to_blacklist(self, user_id, reason):
"""加入黑名单"""
user = db.query("SELECT * FROM users WHERE id = ?", (user_id,))[0]
# 记录到黑名单
db.execute(
"""INSERT INTO blacklist (user_id, email, ip, reason, created_at)
VALUES (?, ?, ?, ?, ?)""",
(user_id, user['email'], user['last_login_ip'],
reason, datetime.now())
)
# 释放该用户抢注的别名
db.execute(
"UPDATE urls SET status = 'released' WHERE user_id = ? AND is_custom = TRUE",
(user_id,)
)
# 释放的别名可以被重新注册
released = db.query(
"SELECT custom_alias FROM urls WHERE user_id = ? AND is_custom = TRUE",
(user_id,)
)
for alias in released:
logging.info(f'别名 "{alias["custom_alias"]}" 已被释放')
logging.warning(f'用户 {user_id} 已加入黑名单: {reason}')完整流程
def register_custom_alias(user_id, alias):
"""注册自定义别名(带防护)"""
# 1. 基本验证
if not validate_alias(alias):
return {'error': '别名格式不合法'}
# 2. 商标检查
trademark = TrademarkChecker()
tm_result = trademark.check(alias)
if tm_result['hit']:
return {
'error': f'该别名涉及品牌保护关键词',
'detail': '如需使用,请提供商标授权证明',
'contact': 'alias-dispute@short.url'
}
# 3. 频率限制
limiter = AliasRateLimiter()
rate_result = limiter.check(user_id)
if not rate_result['allowed']:
return {'error': rate_result['reason']}
# 4. 重复检查
exists = db.query(
"SELECT id FROM urls WHERE custom_alias = ?", (alias,)
)
if exists:
return {'error': '该别名已被注册'}
# 5. 创建别名
db.execute(
"UPDATE urls SET custom_alias = ?, is_custom = TRUE WHERE user_id = ? AND short_code = ?",
(alias, user_id, short_code)
)
return {'success': True, 'alias': alias}成效
上线防护后的一周:
| 指标 | 防护前 | 防护后 |
|---|---|---|
| 品牌名注册 | 87 次 | 0 次 |
| 抢注者账号 | 5 个 | 0 个(已拉黑) |
| 正常用户受影响 | — | 2 次误判(已解封) |
| 争议申诉 | — | 1 次(已处理) |
“这让我想到了域名系统的历史——同样的故事,不同的时代。人类总是想抢注好名字然后倒卖。技术可以减少这种行为,但无法完全消除。”
“防抢注搞定了。但付费别名怎么定价?”