实现一个简单的邮箱密码登录账号体系

眼瞅着为大家完成“自动化”功能的华为云服务器还有50天就要过期了,这一个成功运行了400多天的项目也就有要升级的必要了,当然,既然叫升级,那肯定不是简简单单的迁移代码那么简单,而是要对功能进行一个比较全面的升级。

结合自己2个月在字节跳动里实习学到的一些东西,本次升级的目标是:

  • 提供用户功能。用户可以使用邮箱+密码注册,可以使用邮箱找回,登录后继续使用其他服务,使用cookie实现一个简单的登录态。

  • 后端架构主要使用字节已经开源的Hertz框架,数据库使用Gorm、Mysql和Redis。

  • 使用post直接提交请求的方式替代selenium完成打卡。

比较搞笑的是,这个项目开发跨度时间为20天,20天内,由于二十条和新十条的密集发布,打卡是已经不需要打了,所以本文主要是记录所升级的这个简单账号体系的后端实现。

功能展示

登录界面

b154902922f1a958b4b79a7dc646e40b.png

点击立即注册跳转到注册界面:

0d18128b26d5d9fe4695fa6144e583d3.png

在注册界面,输入邮箱、昵称和密码,提交注册

点击注册后,会弹窗要求输入邮箱验证码。

f012d1c97d86534b594cc9b5f45b0344.png

(这一步从设计上来说其实是不太好的)

输入后即可完成注册,之后输入账号加密码进行登录:

f8aab6cc4af122c33f17f89a88472c68.png

密码会在本地直接通过aes和md5加密后再传输到服务器,服务器直接保存密文,不能反向读取明文。

成功登录后进入到主页面:

a0e0b0891848d5be5e43095d090eb593.png

轮询机制实现的单点登录、登录过期

1efd3245908c404ff92a845cb4fd922f.png

如果在浏览器禁用了每分钟校验的定时任务,登录会过期,但不刷新,当刷新或点击新的页面时过期。

日志系统,对于所有登录地点对IP进行记录,对之后支持的所有自动化操作,对行为进行记录,并支持查询:

65cdce39dc859394c93013860f06546d.png

提供登出操作,在右上角,点击登出后,登录态过期。

这就是一个简单的账号体系应该具备的功能,当然还有修改和找回密码,由于这个系统暂时没有市场了,所以就先不做了,但是理论上很简单。

实现原理

由于前端基本上是拼拼凑凑出来的,主要着重后端的实现原理。

后端的框架采用字节跳动使用的Hertz框架,去搜索一下就可以找到使用教程,当然,由于之前实习使用过Hertz框架,所以还算熟悉。

04a55f36010628f5209825e2fda33b3a.png

刚使用Hertz生成时的文件结构如上图,router是一个路由文件,里面会记录各个接口支持的协议类型,访问接口时调用的回调函数。

本项目实现了以下接口:

// 使用CORS中间件,否则会报跨域错误
  r.Use(cors.New(cors.Config{
    AllowOrigins:     []string{"http://txcloud.z-coding.cn"},
    AllowCredentials: true,
  }))


  g1 := r.Group("/needlogin")


  r.GET("/ping", handler.Ping)
  // 登录态检查中间件,对于需要登录态才能访问的接口检查登录态
  g1.Use(CheckLogin())


  // 登录登出改密换绑
  r.POST("/login", handler.Login)
  g1.GET("/logout", handler.Logout)
  g1.POST("/change_password", handler.ChangePwd) //! TODO


  // 注册
  r.POST("/user_register", handler.UserRegister)
  g1.POST("/ahr_register", handler.AhrRegister) // 打卡注册调用接口


  // 验证
  r.POST("/mail_verify", handler.EmailVerify) // 邮箱验证调用接口
  r.GET("/session_verify/", handler.SessionVerify) // session_id 有效性核查


  //查询
  g1.GET("/bind_stuid", handler.StuidQuery)
  g1.GET("/report_once", handler.ReportOnce)
  g1.GET("/remove_bind", handler.RemoveBind)
  g1.GET("/query_ops", handler.GetLogs) // 获得日志调用接口
}

和打卡有关的接口均不再介绍。

数据库结构:

和登录相关的数据库结构如下图:

5ea17cbaef46a9e3b2c49afe7fcd802c.png

注册流程:

cd6bd19169e314818114c95f38467d05.png

登录流程:

3f333f51ee646378f6b37148cd2bda91.png

session查验流程比较简单,读取cookie中的session_id查看这个session_id在当前IP下与uid的双向绑定关系是否存在,如果双向绑定关系存在,则session_id有效,当session_id无效时,删除cookie,失去登录态。这个流程前端每一分钟核查一次。

通过这样的设计,可以实现防止session_id被用于异地登录以及实现单点登录,因为在redis中,uid始终只能与一个session_id+IP的组合实现映射,当另一个浏览器登录时,uid的映射关系会被替换,使得原session_id立即失效,由于session_id与IP绑定,当一个session_id被用于不在同一IP下的浏览器登录时,也会校验失败,同时,通过对redis有效时间的设置,使得session_id存在时效性,在一段时间后会自动过期,通过session的机制,实现了防异地、单点、包含时效性的登录体系。

存在的问题:

仅仅实现了一个简单的账密登录体系,值得一提的是,账密登录是安全性最低的登录方式之一,可能甚至不如邮箱验证码登录,不过邮箱验证码登录和注册是十分相似的,可以轻松实现。另外一个需要注意的是接口安全性问题,现在的接口不加保护是不安全的,有可能会有刷接口导致验证邮件滥发的可能,应该像其他网站一样,设置间隔期,比如在1分钟内按IP、email维度,只能发送一条,这一点可以通过redis实现。

这样就实现了一个简单的邮箱账密登录账号体系的练手项目,后期如果有其他像打卡一样可以实现自动化的项目,也会继续将这个网站开发下去,不过目前网站不会开放使用。

项目地址:

https://github.com/Jun-marlos/auto-service

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值