手摸手,带你用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相关方法,线程就会进入阻塞状态 ...
随机推荐
- 3D深色金属哥特3D项目工具小图标icon高清设计素材
3D深色金属哥特3D项目工具小图标icon高清设计素材
- 新代(Syntec)机床的IP设置
一.前言 通过以太网来做机床联网数据采集时,第一步通常是设置机床的IP和找网口 二.机床IP如何设置? 步骤一.找到设置IP的界面 [维护]>[网络设定] 步骤二.设置IP 设定[IP地址取得方 ...
- 1.HTML入门
1.1 初识HTML 1.1.1 概述 网络世界已经跟我们息息相关,当我们打开一个网站,首先映入眼帘的就是一个个华丽多彩的网页.这些网页,不仅呈现着基本的内容,还具备优雅的布局和丰富的动态效果,这一切 ...
- Jenkins 基础篇 - Server 配置
我们使用 Jenkins 部署服务之前要先配置我们的目标服务器,配置目标服务器也很简单,就是将服务器的 IP.账号密码或者账号密钥配置在 Jenkins中.在演示服务器配置之前我们要先知道 Linux ...
- 并发王者课 - 青铜4:synchronized用法初体验
在前面的文章<双刃剑-理解多线程带来的安全问题>中,我们提到了多线程情况下存在的线程安全问题.本文将以这个问题为背景,介绍如何通过使用synchronized关键字解这一问题.当然,在青铜 ...
- [刷题] 437 Paths Sum III
要求 给出一棵二叉树及一个数字sum,判断这棵二叉树上存在多少条路径,其路径上的所有节点和为sum 路径不一定始于根节点,终止于叶子节点 路径要一直向下 思路 分情况讨论:根节点在路径上(8) / 根 ...
- 033.Python的__del__析构方法he__call__方法
一 __del__ 魔术方法(析构方法) 1.1 介绍 触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量 2.所有对象被del的时候] 功能:对象使用完毕后资源回收 参数:一个s ...
- Python发送SMTP邮件指南
SMTP(Simple Mail Transfer Protocol)简单邮件传输协议,Python内置对SMTP的支持,可以发送纯文本文件,HTML邮件以及附带文件. 一.两个模块 Pyth ...
- GO学习-(19) Go语言基础之网络编程
Go语言基础之网络编程 现在我们几乎每天都在使用互联网,我们前面已经学习了如何编写Go语言程序,但是如何才能让我们的程序通过网络互相通信呢?本章我们就一起来学习下Go语言中的网络编程. 关于网络编程其 ...
- 机器学习PAL数据预处理
机器学习PAL数据预处理 本文介绍如何对原始数据进行数据预处理,得到模型训练集和模型预测集. 前提条件 完成数据准备,详情请参见准备数据. 操作步骤 登录PAI控制台. 在左侧导航栏,选择模型开发和训 ...