前言
本篇博客记录登录功能,找回密码功能接口的后端接口,前端页面以及功能测试。
后端接口
路由地址:user/login登录接口
user/update_password更新密码接口
app.post(self.generate_route_path(["login"]), tags=self.tag, summary="用户登录")(user_service.login_user)
app.post(self.generate_route_path(["update_password"]), tags=self.tag, summary="更新密码")(user_service.update_password)
app.post(self.generate_route_path(["update_info"]), tags=self.tag, summary="更新用户信息")(
user_service.update_info)
登陆接口逻辑:1.接受前端传过来的登录表单信息,查询数据库是否存在该用户。并根据相应处理逻辑返回“帐号不存在”,“密码错误”,“帐号被封禁”,“登陆成功”四种状态。前端根据状态码提示用户信息。
关键点:要根据用户的email以及普通用户生成一个token,便于后面实现接口拦截和用户验证功能。
修改密码接口逻辑:根据前端传过来的数据,先查找该用户是否存在,若不存在则返回错误信息。若存在则更新新的密码。
async def update_password(login_form: LoginForm):
session = Session(bind=engine)
try:
# 根据用户邮箱查询用户
user = session.query(User).filter(User.email == login_form.email).first()
if not user:
return BaseResponse(code=400, msg='账号不存在')
# 更新用户密码
user.password=login_form.password
session.commit()
return {"code": 200, "message": "密码更新成功"}
except Exception as e:
session.rollback() # 发生异常时回滚事务
raise HTTPException(status_code=500, detail="密码更新失败,请重试")
finally:
session.close()
async def login_user(login_form: LoginForm):
"""
用户登录接口
LoginForm 包含 email 和 password 字段
"""
session = Session(bind=engine)
try:
# 根据邮箱查询用户
user = session.query(User).filter(User.email == login_form.email).first()
if not user:
return BaseResponse(code=400, msg='账号不存在')
# 对用户输入的密码进行MD5加密
input_password_hash = md5(login_form.password.encode('utf-8')).hexdigest()
# 验证密码是否正确
if user.password != input_password_hash:
return BaseResponse(code=401, msg='密码错误')
if not user.is_active:
return BaseResponse(code=402, msg='账号被封禁')
# 登录成功,在此处生成token
# token = generate_token(user.email)
access_token_expires = timedelta(minutes=JWT_ARGS["expire_time"])
access_token = create_access_token(
data={"sub": user.email, "index": 0}, expires_delta=access_token_expires # index索引是0代表用户,1代表管理员
)
return {"code": 200, "message": "登录成功",
"data": {"token": access_token, "token_type": "bearer", "user_id": user.id}}
except Exception as e:
return BaseResponse(code=500, msg='登陆失败请重试')
finally:
session.close()
前端页面
普通用户登录功能
- 用户可以通过填写邮箱和密码来登录系统。登录表单使用
el-form
组件,并通过v-model
双向绑定数据到loginForm
对象。 - 登录按钮通过点击事件触发
login
方法,该方法首先验证表单是否有效。如果有效,调用login
服务函数发送登录请求。 - 登录成功后,会将用户重定向到聊天页面,并显示成功消息。登录失败会根据不同的错误代码显示相应的警告消息。
找回密码功能
- 用户可以通过点击“忘记密码”链接来触发找回密码的流程。这会打开一个弹窗,其中包含找回密码的表单。
- 找回密码表单与注册表单共享相同的结构,但逻辑上用于更新密码。表单验证确保用户输入了邮箱、验证码、新密码和确认密码。
- 用户提交找回密码表单后,调用
submitForgetPassword
方法,该方法验证表单有效性并调用update_password
服务函数来更新密码。 - 如果用户不存在、验证码错误或密码修改成功,都会显示相应的消息。
表单验证
- 表单验证使用Element UI的
el-form
和el-form-item
组件,结合自定义的验证方法。 - 验证方法包括:
validPass
:验证两次输入的密码是否一致。valid_regis_password
:验证密码复杂性,包括长度和字符类型。valid_email
:使用正则表达式验证邮箱格式。valid_code
:验证验证码是否为6位数字。
- 每个
el-form-item
组件都绑定了相应的验证规则,当用户输入不符合规则时,会显示错误提示。
var valid_regis_password = (rule, value, callback) => {
if (value.length < 8 || value.length > 16) {
callback(new Error('密码长度在8~16位之间'))
}
if (checkPass(value)) {
callback()
} else {
callback(new Error('密码必须包含数字、小写字母、大写字母、下划线\'_\'中的至少两种'))
}
}
var valid_email = (rule, value, callback) => {
if (/\w*@.*/.test(value)) {
callback()
} else {
callback(new Error('请输入正确的邮箱'))
}
}
var valid_code = (rule, value, callback) => {
if (/\d{6}/.test(value)) {
callback()
} else {
callback(new Error('请输入6位数字验证码'))
}
}
效果展示
普通用户登录
修改密码