一、 为什么你的“修改密码”按钮像个摆设?
想象一下:用户兴冲冲点开修改密码,结果要么旧密码输错被怼,要么新密码规则复杂到想摔键盘,最后干脆选择“忘记密码”绕路走——这就是失败密码修改功能的真实写照。
在Django世界里,自带django.contrib.auth模块虽然提供了现成的用户认证工具,但直接搬用默认视图可能让产品经理提着40米大刀来找你。比如默认密码修改流程会强制退出登录,用户体验堪比半夜被房东赶出家门。
别方!今天咱们就用**“糙快猛”的实战思路**,手搓一个兼具安全性和人性的密码修改功能,附赠防止手残党设弱密码的秘籍!
二、 解剖Django密码修改的“五脏六腑”
1. 核心装备库:Auth模块绝活揭秘
check_password(raw_password, encoded_password):
像验钞机一样核对旧密码,返回True/False,自动处理加密后的密码对比set_password(raw_password):
给新密码做“加密马杀鸡”,转换成pbkdf2_sha256格式的乱码update_session_auth_hash(request, user):
修改密码后续命登录状态的神器!缺了它用户直接掉线
2. 流程设计:密码修改的三大生死关
- 身份验证关:确认是本人操作(别让隔壁老王钻空子)
- 新密码合规关:长度/复杂度检查(防止设成123456)
- 数据持久化关:安全存储且不踢用户下线(温柔点别粗暴)
三、 手把手造轮子:从零写密码修改视图
1. 建个带安全校验的视图函数
# views.py
from django.contrib import messages
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
@login_required
def change_password(request):
if request.method == 'POST':
old_password = request.POST.get('old_password')
new_password1 = request.POST.get('new_password1')
new_password2 = request.POST.get('new_password2')
user = request.user
# 第一关:旧密码验明正身
if not user.check_password(old_password):
messages.error(request, '原密码输错了亲,再想想?')
return render(request, 'change_password.html')
# 第二关:确认新密码是否手抖输错
if new_password1 != new_password2:
messages.error(request, '两次新密码咋不一致?')
return render(request, 'change_password.html')
# 第三关:密码强度检测(自定义规则)
if len(new_password1) < 8:
messages.error(request, '密码至少8位,别偷懒!')
return render(request, 'change_password.html')
# 全部通关!执行密码修改
user.set_password(new_password1)
user.save()
# 关键操作:保持登录状态
update_session_auth_hash(request, user)
messages.success(request, '密码修改成功!继续嗨~')
return redirect('user_profile')
return render(request, 'change_password.html')
2. 做个接地气的模板
<!-- change_password.html -->
<!DOCTYPE html>
<html>
<head>
<title>修改密码-千万别忘</title>
</head>
<body>
<h2>修改密码</h2>
<!-- Django消息提示 -->
{% if messages %}
{% for message in messages %}
<div style="color: {% if message.tags == 'error' %}red{% else %}green{% endif %}">
{{ message }}
</div>
{% endfor %}
{% endif %}
<form method="post">
{% csrf_token %}
<div>
<label>原密码:</label>
<input type="password" name="old_password" required>
</div>
<div>
<label>新密码:</label>
<input type="password" name="new_password1" required>
<small>至少8位,建议字母+数字组合</small>
</div>
<div>
<label>确认新密码:</label>
<input type="password" name="new_password2" required>
</div>
<button type="submit">确认修改</button>
</form>
</body>
</html>
3. 配置路由(urls.py)
from django.urls import path
from . import views
urlpatterns = [
path('change-password/', views.change_password, name='change_password'),
]
四、 防坑指南:那些年我们踩过的雷
1. 修改密码后莫名退登录?
缺了update_session_auth_hash()!Django默认修改密码后会刷新用户会话,这个函数就是帮你“续费”登录状态的。
2. 想自定义密码规则?
在settings.py加配置:
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
'OPTIONS': {'min_length': 10} # 改成至少10位
},
# 其他验证规则...
]
3. 需要Ajax异步验证?
改造视图返回JSON:
from django.http import JsonResponse
if request.is_ajax():
if not user.check_password(old_password):
return JsonResponse({'status': 'error', 'msg': '旧密码错误'})
return JsonResponse({'status': 'success'})
五、 高端玩法:给密码修改加“特效”
1. 添加密码强度实时检测
在前端加入zxcvbn库:
<script src="https://cdnjs.cloudflare.com/ajax/libs/zxcvbn/4.4.2/zxcvbn.js"></script>
<script>
document.getElementById('id_new_password1').addEventListener('input', function() {
let strength = zxcvbn(this.value).score;
let strengthText = ['弱', '一般', '中等', '强', '非常强'];
document.getElementById('password-strength').innerText =
'密码强度:' + strengthText[strength];
});
</script>
2. 记录密码修改历史
建个模型存历史密码:
class PasswordHistory(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
encrypted_password = models.CharField(max_length=128)
created_at = models.DateTimeField(auto_now_add=True)
六、 总结:别让密码修改成为用户体验的崩塌现场
一个合格的密码修改功能,应该像靠谱的门卫——既严格核查身份,又不会每次进门都让你重新办卡。通过今天的学习,你不仅学会了用Django原生工具实现密码修改,更掌握了提升用户体验的关键技巧:
- 旧密码验证用
check_password()准没错 - 修改后保活靠
update_session_auth_hash() - 前端体验加点实时检测更友好
- 安全加固通过密码历史记录防重复
下次产品经理再让你做密码功能,直接把文章拍他脸上:“这次我要造个让用户爽的安全系统!”
3万+

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



