ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

手摸手,带你用Beego撸商城系列二(登录篇)

2021-06-30 08:31:54  阅读:213  来源: 互联网

标签:Beego http 登录 err member Controller address 手摸 商城


完整项目地址: go-shop-b2c

系列文章:

前言

一个商城后端系统,登录尤其重要,首先用户下单,需要登录,后台管理系统,需要登录。我们需要做的是,除了登录以及注册,其余的接口需要进行登录校验。

base_controller 封装

由于我们需要进行登录校验和不进行登录校验的 Controller,又由于 base_controller 需要进行登录检验,同时,不需要登录校验的 Controllerbase_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 方法之前执行,用户可以重写这个函数实现类似用户验证之类。点击跳转文档查看方法

主要做三件事

  1. gob 序列化保存用户信息
    ps: 序列化某个对象,必须在 encoding/gob 编码解码前进行注册

  2. session 中获取用户信息

  3. 如果 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,http,登录,err,member,Controller,address,手摸,商城
来源: https://www.cnblogs.com/alfred-y/p/14952805.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有