手摸手,带你用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相关方法,线程就会进入阻塞状态 ...
随机推荐
- Docker镜像讲解
Docker镜像讲解 镜像是什么 镜像是一种轻量级的,可执行的独立软件包,用来打包软件运行环境和基于运行环境的开发软件,它包含运行某个软件做需要的所有的内容,包括代码,运行时,库,环境变量和配置文件. ...
- Django(27)类视图
类视图 在写视图的时候,Django除了使用函数作为视图,也可以使用类作为视图.使用类视图可以使用类的一些特性,比如继承等. View django.views.generic.base.View是主 ...
- 列出系统上的存储库,状态是enabled [root@blog ~]# dnf repolist
DNF 和 YUM 均是 rpm 软件包管理工具,但是 DFN 替代 YUM 的说法由来已久,因为 YUM 包管理工具有一些问题长期得不到解决. 这些问题包括性能低下.内存占用高以及依赖包解决方案不佳 ...
- [转发]Linux性能测试工具之Lmbench特性、安装及使用
Linux性能测试工具之Lmbench特性.安装及使用2015年07月16日 10:13:48 Michaelwubo 阅读数:2466Linux性能测试工具Lmbench 是一套简易可移植的,符合A ...
- Ansible playbook编写Apache角色
编写Apache角色:使用源码安装 在files中下载扩展包和安装包 [root@localhost project]# ls roles/httpd/files/ apr-1.6.5.tar.gz ...
- VUE如何关闭代码规范extra semiclon/VUE新手必看-(转载)
VUE如何关闭代码规范 最近在学VUE,作为一个设计转前端的小白鼠. 总是能碰到各种各样奇葩的问题. 比如我碰到了 extra semicolon 百度了下说是这个原因造成的: 但是!!!!!关键点来 ...
- Python基础之PyCharm快捷键大全
Pycharm中打开Help->Keymap Reference可查看默认快捷键帮助文档 一.编辑(Editing) Ctrl + Space 基本的代码完成(类.方法.属性) Ctrl + A ...
- ifconfig显示的网卡信息和我的配置文件名不符
比如我的配置文件, cd /etc/sysconfig/network-scripts/ifcfg-Auto_eth0是这个名称,但是我使用ifconfig显示的信息却是 eth6 Link en ...
- Redis学习笔记七:主从集群
单机,单节点,单实例的Redis会有什么问题呢? 容易导致单点故障,那么如何解决呢? 可以通过主备方式 同时可以实现读写分离 这里的每个节点是全量的,镜像的. 单节点的容量有限而且单点的压力比较大,如 ...
- Go语言常用命令
查看可用命令 直接在终端中输入 go help 即可显示所有的 go 命令以及相应命令功能简介,主要有下面这些: ·build: 编译包和依赖 ·clean: 移除对象文件 ·doc: 显示包或者符号 ...