手摸手,带你用Beego撸商城系列二(登录篇)
完整项目地址: go-shop-b2c
系列文章:
前言
一个商城后端系统,登录尤其重要,首先用户下单,需要登录,后台管理系统,需要登录。我们需要做的是,除了登录以及注册,其余的接口需要进行登录校验。
base_controller 封装
由于我们需要进行登录校验和不进行登录校验的 Controller,又由于 base_controller 需要进行登录检验,同时,不需要登录校验的 Controller 和 base_controller有共同的函数需要调用
综上所述,我们应该额外增加一个 Controller 分别用于 base_controller 继承 和 不需要登录检验的 Controller 用于继承
下面就简单地介绍一下 json_controller
json_controller
type JsonController struct {
beego.Controller
}
- JsonResult 返回给前端JSON数据,公共调用函数
/**
* Ajax接口返回Json
*/
func (c *JsonController) JsonResult(status int, errCode int, errMsg string, data ...interface{}) {
jsonData := make(map[string]interface{}, 3)
jsonData["err_code"] = errCode
jsonData["message"] = errMsg
if len(data) > 0 && data[0] != nil {
jsonData["data"] = data[0]
}
c.Ctx.Output.SetStatus(status)
c.Data["json"] = jsonData
c.ServeJSON()
}
- ServerError 服务器通用报错
/**
* 服务器报错
*/
func (c *JsonController) ServerError(err error) {
c.Ctx.Output.SetStatus(http.GetHttpStatusByAlias("internalServerError"))
logs.Error(err)
}
- SetSessionUser 封装保存session的函数
/**
* 设置登录登录用户session信息
*/
func (c *JsonController) SetSessionUser(member models.Member) {
if member.Id <= 0 {
c.DelSession(common.SessionName)
c.DelSession("uid")
c.DestroySession()
} else {
c.SetSession(common.SessionName, member)
c.SetSession("uid", member.Id)
}
}
登录检验
在 beego 的 Prepare 函数调用
简单说一下Prepare函数的作用,这个函数主要是为了用户扩展用的,这个函数会在下面定义的这些 Method 方法之前执行,用户可以重写这个函数实现类似用户验证之类。点击跳转文档查看方法
主要做三件事
gob 序列化保存用户信息
ps: 序列化某个对象,必须在 encoding/gob 编码解码前进行注册从 session 中获取用户信息
如果 Cookie 中存在登录信息,从 cookie 中获取用户信息
在其它 Controller 基本写法
主要分类,需要登录检验和不需要登录检验的 Controller,不需要登录校验通常是包含登录和注册的 Controller
需要登录检验的 Controller编写
以 address_controller 为例
截取部分代码
// 需要登录校验就需要继承 BaseController,这样该 Controller下的函数都在调用执行之前到 执行Prepare函数进行登录检验
type AddressController struct {
BaseController
}
// URLMapping ...
func (c *AddressController) URLMapping() {
c.Mapping("AddAddress", c.AddAddress)
c.Mapping("DeleteAddress", c.DeleteAddress)
c.Mapping("UpdateAddress", c.UpdateAddress)
c.Mapping("GetAllAddress", c.GetAllAddress)
}
// @Title 新增地址
// @router /add [post]
func (c *AddressController) AddAddress() {
var address model_views.Receiver
if v := c.GetString("address"); v != "" {
_ = json.Unmarshal([]byte(v), &address)
}
var receiver models.Receiver
receiver.Id = address.Id
receiver.Consignee = address.Consignee
receiver.AreaName = address.AreaName
receiver.AreaId = address.AreaId
receiver.Address = address.Address
receiver.IsDefault = address.IsDefault
receiver.Phone = address.Phone
receiver.ZipCode = address.ZipCode
receiver.MemberId = int64(c.Member.Id)
receiver.LastUpdatedBy = c.Member.Username
_, err := models.AddReceiver(&receiver)
if err != nil {
// 服务通用报错函数调用
c.ServerError(err)
return
}
c.JsonResult(http.GetHttpStatusByAlias("created"), http.ErrOK, http.Success, nil)
}
就是这么简单,其它 Controller 基本都是如此
不需要登录检验的 Controller 编写
截取部分代码
// 继承 JsonController,不会调用 BaseController 的Prepare函数进行登录校验
type UserController struct {
JsonController
}
// @Title 登录
// @router /login [post]
func (c *UserController) Login() {
var mobile string
var sms string
// mobile
if v := c.GetString("mobile"); v != "" {
mobile = v
}
// sms
if v := c.GetString("sms"); v != "" {
sms = v
}
smsModel, err := models.GetSmsByCodeAndMobile(sms, mobile)
if err != nil {
c.JsonResult(http.GetHttpStatusByAlias("ok"), http.ErrError, http.Fail, "手机和验证码不匹配")
return
}
if smsModel.ExpireDate != nil {
c.JsonResult(http.GetHttpStatusByAlias("ok"), http.ErrError, http.Fail, "验证码已过期")
return
}
if smsModel.IsUsed == 1 {
c.JsonResult(http.GetHttpStatusByAlias("ok"), http.ErrError, http.Fail, "验证码已使用")
return
}
member, _ := models.GetMemberByUsername(mobile)
if member == nil {
member = &models.Member{}
}
if member.Id > 0 {
// 最后登录IP
member.LoginIp = c.Ctx.Input.IP()
member.LoginDate = time.Now()
err = models.UpdateMemberById(member)
if err != nil {
c.ServerError(err)
return
}
} else {
member.Username = mobile
member.Mobile = mobile
member.MemberRankId = 1 // 普通会员
_, err := models.AddMember(member)
if err != nil {
c.ServerError(err)
return
}
}
/**
* 更新短信使用
*/
now := time.Now()
smsModel.UsedDate = &now
smsModel.IsUsed = 1
err = models.UpdateSmsById(smsModel)
if err != nil {
c.ServerError(err)
return
}
/**
* 设置Cookie
*/
c.SetSessionUser(*member)
var cookieMember CookieMember
cookieMember.MemberId = member.Id
cookieMember.Username = member.Username
cookieMember.Time = time.Now()
v, err := helpers.Encode(cookieMember)
if err == nil {
c.SetSecureCookie(common.AppKey(), "web_login", v, 24*3600)
}
commonController := &CommonController{}
memberView := commonController.setMemberByMemberModel(*member)
c.JsonResult(http.GetHttpStatusByAlias("ok"), http.ErrOK, http.Success, memberView)
}
总结
最后,写完这两个基础的 Controller 后,基本就是根据业务判断是否需要登录校验,然后就行CRUD(增删改查)的业务编写就好了,没错就是这么简单
手摸手,带你用Beego撸商城系列二(登录篇)的更多相关文章
- 手摸手,带你用Beego撸商城系列一(基础篇)
完整项目地址: go-shop-b2c 系列文章: 手摸手,带你用 Beego撸商城 系列一(基础篇) 手摸手,带你用 Beego撸商城 系列二(登录篇) 手摸手,带你用 Beego撸商城 系列三(系 ...
- 【转】手摸手,带你用vue撸后台 系列二(登录权限篇)
前言 拖更有点严重,过了半个月才写了第二篇教程.无奈自己是一个业务猿,每天被我司的产品虐的死去活来,之前又病了一下休息了几天,大家见谅. 进入正题,做后台项目区别于做其它的项目,权限验证与安全性是非常 ...
- 【转】手摸手,带你用vue撸后台 系列三(实战篇)
前言 在前面两篇文章中已经把基础工作环境构建完成,也已经把后台核心的登录和权限完成了,现在手摸手,一起进入实操. Element 去年十月份开始用vue做管理后台的时候毫不犹豫的就选择了Elemen, ...
- 【转】手摸手,带你用vue撸后台 系列四(vueAdmin 一个极简的后台基础模板)
前言 做这个 vueAdmin-template 的主要原因是: vue-element-admin 这个项目的初衷是一个vue的管理后台集成方案,把平时用到的一些组件或者经验分享给大家,同时它也在不 ...
- 【转】手摸手,带你用vue撸后台 系列一
前言 说好的教程终于来了,第一篇文章主要来说一说在开始写业务代码前的一些准备工作吧,但这里不会教你webpack的基础配置,热更新怎么做,webpack速度优化等等,有需求的请自行google. 目录 ...
- 手摸手带你用Hexo撸博客(二)之配置主题
在上一篇博客手摸手带你用Hexo撸博客(一)中主要介绍了博客的初步搭建 今天我们继续讲如何在Hexo搭建的博客中应用主题 官网选择自己喜欢的主题 点击这里Hexo主题进入官网主题页面 然后选择自己喜欢 ...
- 手摸手带你用Hexo撸博客(一)
原文地址 手摸手带你用Hexo撸博客(一) 环境搭建 安装 node 狂点下一步 命令行输入此条命令 如果能看到版本号则安装成功 node -v 安装Git (同上) 实在不会的小伙伴百度一下,教程很 ...
- 原创 | 手摸手带您学会 Elasticsearch 单机、集群、插件安装(图文教程)
欢迎关注笔者的公众号: 小哈学Java, 每日推送 Java 领域干货文章,关注即免费无套路附送 100G 海量学习.面试资源哟!! 个人网站: https://www.exception.site/ ...
- 浅谈Java中的Condition条件队列,手摸手带你实现一个阻塞队列!
条件队列是什么?可能很多人和我一样答不出来,不过今天终于搞清楚了! 什么是条件队列 条件队列:当某个线程调用了wait方法,或者通过Condition对象调用了await相关方法,线程就会进入阻塞状态 ...
随机推荐
- 异步阻塞,Manager模块,线程
一.异步阻塞 1.并没有按照执行顺序等待结果 2.而是所有的任务都在异步执行着 3.但是我要的结果又不知道谁的结果先来,谁先结束我就先取谁的结果 很明显的异步,大家都相互执行着(异步过程),谁先结束我 ...
- JPEG头部解析
6.3 JPEG格式 6.3.1简介 微处理机中的存放顺序有正序(big endian)和逆序(little endian)之分.正序存放就是高字节存放在前低字节在后,而逆序存放就是低字 ...
- Scrum Meeting 1
Basic Info where:新主楼 when:2020/4/23 target: 简要汇报一下已完成任务,下一步计划与遇到的问题 Progress Team Member Position Ac ...
- 日常Bug排查-系统失去响应-Redis使用不当
日常Bug排查-系统失去响应-Redis使用不当 前言 日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_. Bug现场 开发反应线上系统出现失去响 ...
- [c++] 内存与变量
内存 程序代码区用来保存指令,常量区.全局数据区.堆.栈都用来保存数据 常量区和全局数据区有时也被合称为静态数据区,意思是这段内存专门用来保存数据,在程序运行期间一直存在 函数被调用时,会将参数.局部 ...
- 063.Python前端Django分页器
Django的分页器 1 前期准备 创建一个数据库,用于存放数据 mysql> create database pager default charset=utf8; mysql> use ...
- Linux服务之DHCP服务篇(scp)
一.概念 名称:DHCP----Dynamic Host Configuration Protocol 动态主机配置协议 功能:DHCP是一个局域网的网络协议,使用UDP协议工作 主要用途:给内部网络 ...
- CAP 与数据一致性
分布式系统的假设是,工作在网络环境下的系统拥有多个节点,而这些节点本身会由于各种原因而变得不稳定.这其中就有一个非常重要的概念--CAP原理.这个原理指导着大多数分布式系统的设计过程,CAP原理大致是 ...
- 10.8 ss:查看网络状态
ss命令 是类似并将取代netstat的工具,它能用来查看网络状态信息,包括TCP.UDP连接.端口等.它的优点是能够显示更多更详细的有关网络连接状态的信息,而且比netstat更快速更高效. ...
- 如何在idea中将项目生成API文档(超详细)(Day_32)
1.打开要生成API文档的项目,点击菜单栏中的Tools工具,选择Generate JavaDoc 2.打开如下所示的Specify Generate JavaDoc Scope 界面 3.解释下Ot ...