beego开发轻博客——第四讲 用户登陆和注册

【小鸡创作】beego开发轻博客

本章目标:添加用户登陆及注册功能!
github: 打开后,点击右上角star按钮
视频教程: B站地址


初始化数据-数据库选用sqlite3数据库

  1. 安装 gorm框架 点我进入官方文档
go get -u github.com/jinzhu/gorm
  1. 创建 models->core.go 初始化gorm
import (
    "github.com/jinzhu/gorm"
     //引入sqlite3的驱动
    _ "github.com/jinzhu/gorm/dialects/sqlite"
    "os"
)
var (
     //定义db变量,变量名开头是小写,只能同包下访问
    db gorm.DB
)
func init() {
    // 创建data目录,0777代表文件权限
    if err := os.MkdirAll("data", 0777); err != nil {
        panic("failed to connect database," + err.Error())
    }
    //打开数据库,并复制给db变量,data/data.db数据文件路径
    db, err := gorm.Open("sqlite3", "data/data.db")
   //存在错误,则程序退出,panic是类似于java的RuntimeException错误
    if err != nil {
        panic("failed to connect database")
    }
}
  1. 在main.go调用 core.go的init方法
import (
    // 运行main方法之前 调用models包下的文件的init方法。先初始化数据库
    _ "github.com/jicg/liteblog/models"
    ...
)
func main(){
   ...
}

定义用户表

  1. 用户表有的字段:邮件、用户名、密码、头像,角色(管理员\非管理员)
  2. 新增models->user.go 文件,定义用户表字段。
type User struct {
    gorm.Model
    Name   string `gorm:"unique_index"`
    Email  string `gorm:"unique_index"`
    Avatar string
    Pwd    string
    Role   int    `gorm:"default:1"` // 0 管理员 1正常用户
}
  1. 让gorm自动同步 用户表结构,只需在models-core.go init方法后面添加如下代码
func init(){
    ......
    // 自动同步表结构
    db.AutoMigrate(&User{})
}
  1. 程序启动的时候默认插入admin用户,即修改models->core.go文件,在init的方法结尾,判断用户是否存在记录,不存在就插入admin用户。
func init(){
    ......
    // 自动同步表结构
    db.AutoMigrate(&User{})
    var count int
    // Model(&User{})查询用户表, Count(&count) 将用户表的数据赋值给count字段。
    if err := db.Model(&User{}).Count(&count).Error; err == nil && count == 0 {
        //新增
        db.Create(&User{Name: "admin",
            //邮箱
            Email: "admin@qq.com",
            //密码
            Pwd: "123123",
            //头像地址
            Avatar: "/static/images/info-img.png",
            //角色 管理员
            Role: 0,
        })
    }
}

xianyan 框架没有用户登陆与注册界面

  1. 新增用户页面:views->user.html点我查询页面代码
    用户登陆界面效果
  2. 新增用户注册也页面 views->reg.html点我查询页面代码
    用户注册页面效果

启用beego的session功能

  1. 修改main.go,开启beego的session功能
func main() {
    initSession()
    ...
}
func initSession() {
    //beego的session序列号是用gob的方式,因此需要将注册models.User
    gob.Register(models.User{})
    //https://beego.me/docs/mvc/controller/session.md
    beego.BConfig.WebConfig.Session.SessionOn = true
    beego.BConfig.WebConfig.Session.SessionName = "liteblog-key"
    beego.BConfig.WebConfig.Session.SessionProvider = "file"
    beego.BConfig.WebConfig.Session.SessionProviderConfig = "data/session"
}
  1. 使用session功能,每次请求的时候都去判断用户是否登陆。并将登陆的信息保存到BaseController控制器里,修改controllers->base.go 文件
//定义session中的key值
const SESSION_USER_KEY = "SESSION_USER_KEY"
...
type BaseController struct {
    beego.Controller
    IsLogin bool //标识 用户是否登陆
    User    models.User //登陆的用户
}
func (ctx *BaseController) Prepare() {
    // 验证用户是否登陆,判断session中是否存在用户,存在就已经登陆,不存在就没有登陆。
    ctx.IsLogin = false
    tu := ctx.GetSession(SESSION_USER_KEY)
    if tu != nil {
        if u, ok := tu.(models.User); ok {
            ctx.User = u
            ctx.Data["User"] = u
            ctx.IsLogin = true
        }
    }
    ctx.Data["IsLogin"] = ctx.IsLogin
    ...
}

用户登陆功能实现

  1. 首先咱们判断用户是否存在,需要到数据库,更具用户名和密码查询用户,如果能查到就存在,反之不存在。因此新增根据用户邮箱和密码查询用户的方法,修改models->user.go,添加下面代码
func QueryUserByEmailAndPassword(email, password string) (user User, err error) {
    // 这就是gorm的魅力,一句代码即可,对开发友好。
    return user, db.db.Model(&User{}).Where("email = ? and pwd = ?", email, password).Take(&user).Error
}
  1. 新增 cotrollers->user.go 用户登陆控制器UserController 代码如下
type UserController struct {
    BaseController
}
// @router /login [post]
func (c *UserController) Login() 
    /*c.GetMustString(agr0,arg1 string ) 是在BaseController里面定义的,第一个参数获取请求的参数的键值对的key,请求后,如key对于的value是空,就返回第二个参数*/
    // 判断邮箱不能为空
    email := c.GetMustString("email", "邮箱不能为空!")
    // 判断密码不能为空!
    pwd := c.GetMustString("password", "密码不能为空!")
    var (
        user *models.User
        err  error
    )
    if user, err = models.QueryUserByEmailAndPassword(email, pwd); err != nil {
     // About500使在BaseController里面定义的,使对beego的ctx.Abort(..)的封装,目的:优化错误提示。   
      c.Abort500(syserrors.NewError("邮箱或密码不对", err))
    }
    //将user保存到session
    c.SetSession(SESSION_USER_KEY, user)
    //JSONOk使在BaseController里面定义的,使对beego的ctx.ServeJSON()的封装,目的:优化提示
    //这里将返回 {code: 0, msg: "登陆成功", action: "/"}
    c.JSONOk("登陆成功", "/")
}
  1. 上面咱们定义好的登陆逻辑,现在我们还需要定义beego的路由。我们使用beego的注解路由,只需要修改 routers->router.go 文件添加下面一段代码
func init() {
    ...
    beego.Include(
        &controllers.IndexController{},
        &controllers.UserController{},
    )
    ...
}
  1. 咱们用户登陆的后台业务已经完成,现在开始修改前台页面,使能够登陆成功。前台页面user.html页面已经新增,其核心代码:
<form class="layui-form" action="">
       <div class="layui-form-item">
            <label class="layui-form-label">邮箱</label>
            <div class="layui-input-inline">
                   <input type="text" name="email" required lay-verify="required"  placeholder="请输入邮箱" autocomplete="off" class="layui-input">
             </div>
        </div>
        <div class="layui-form-item">
                <label class="layui-form-label">密码</label>
                <div class="layui-input-inline">
                    <input type="password" name="password" required lay-verify="required" placeholder="请输入密码"
                                       autocomplete="off" class="layui-input">
                 </div>
         </div>
         <div class="layui-form-item">
                <div class="layui-input-block">
                      <button class="layui-btn" lay-submit lay-filter="login">登陆</button>
                     <a href="/reg" class="layui-btn layui-btn-primary">注册用户</a>
               </div>
          </div>
</form>

咱们要实现这个form表单的提交逻辑,让其和后台打通,修改static->js->blog.js 。其中sysn是对jquery的ajax请求方法的进一步封装查看代码

    // 
    //登陆
    form.on('submit(login)', function (fromdata) {
        //发送ajax请求
        sysn.post("/login", fromdata.field)
             // 设置登陆成功回掉函数
            .success(function (data) {
                // 提示
                layer.msg(data.msg);
                // 后台如果返回有action ,就是跳转到新页面。
                if (data.action) {
                    setTimeout(function () {
                        window.location.href = data.action;
                    }, 300)
                }
            }).run();
        return false;
    });

用户登陆已经完成。

用户注册功能实现

1. 数据库调整

1.1 由于邮箱和昵称不能重复,因此,我们需要新增能够根据用户昵称查询用户和根据用户邮箱查询用户的方法。用来查询数据是否存在。代码如下
//根据昵称查用户
func  QueryUserByName(name string) (user User, err error) {
    return user, db.db.Where("name = ?", name).Take(&user).Error
}
//根据邮箱查用户
func QueryUserByEmail(email string) (user User, err error) {
    return user, db.db.Where("email = ?", email).Take(&user).Error
}
1.2 除了判断重复的问题,最重要的我们还需要提供一个保存用户的方法。代码如下
//   保存用户
func SaveUser(user *User) error {
    return db.Create(user).Error
}

2. 控制器UserController调整

2.1 修改controllers->user.go 添加reg方法,代码如下
// @router /reg [post]
func (c *UserController) Reg() {
    name := c.GetMustString("name", "昵称不能为空!")
    email := c.GetMustString("email", "邮箱不能为空!")
    pwd1 := c.GetMustString("password", "密码不能为空!")
    pwd2 := c.GetMustString("password2", "确认密码不能为空!")
    if strings.Compare(pwd1, pwd2) != 0 {
        c.Abort500(errors.New("密码与确认密码 必须要一致!"))
    }
    if u, err := models.QueryUserByName(name); err == nil &&  u.ID != 0 {
        c.Abort500(syserrors.NewError("用户昵称已经存在!", err))
    }
    if u, err := models.QueryUserByEmail(email); err == nil && u.ID != 0 {
        c.Abort500(syserrors.NewError("用户邮箱已经存在!", err))
    }
    //开始保存用户
    if err := models.SaveUser(&models.User{
        Name:   name,
        Email:  email,
        Pwd:    pwd1,
        Avatar: "",
        Role:   1,
    }); err != nil {
        c.Abort500(syserrors.NewError("用户注册失败", err))
    }
    c.JSONOk("注册成功", "/user")
}

3.修改前台代码

3.1 注册页面的核心代码:
<form class="layui-form" action="">
    <div class="layui-form-item">
        <label class="layui-form-label">昵称</label>
        <div class="layui-input-inline">
            <input type="text" name="name" required lay-verify="required"
                    placeholder="请输入用户名" autocomplete="off" class="layui-input">
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label">邮箱</label>
        <div class="layui-input-inline">
            <input type="text" name="email" required lay-verify="required"
                    placeholder="请输入邮箱" autocomplete="off" class="layui-input">
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label">密码</label>
        <div class="layui-input-inline">
            <input type="password" name="password" required lay-verify="required"
                    placeholder="请输入密码"
                    autocomplete="off" class="layui-input">
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label">确认密码</label>
        <div class="layui-input-inline">
            <input type="password2" name="password2" required lay-verify="required"
                    placeholder="请输入密码"
                    autocomplete="off" class="layui-input">
        </div>
    </div>
    <div class="layui-form-item">
        <div class="layui-input-block">
            <button class="layui-btn" lay-submit lay-filter="reg">注册</button>
            <button type="reset" class="layui-btn layui-btn-primary">重置</button>
        </div>
    </div>
</form>
3.2 修改static->js->blog.js 代码如下
//注册
    form.on('submit(reg)', function (fromdata) {
        sysn.post("/reg", fromdata.field)
            .success(function (data) {
                // 设置登陆成功回掉函数
                layer.msg(data.msg);
                // 后台如果返回有action ,就是跳转到新页面。
                if (data.action) {
                    setTimeout(function () {
                        window.location.href = data.action;
                    }, 300)
                }
            }).run();
        return false;
    });

用户注册功能完成


总结

本讲,我们实现了登陆和注册两个功能。我们程序的大概流程是:页面发送请求 ,beego接收请求,匹配咱们定义好的路由,调用对应的controller方法,再由controller的方法去查数据库,做一些业务的处理,返回结果给页面。我们主要定义好 路由规则(beego的Router)、核心业务逻辑(beego的Controller)、数据库操作的方法,即可。
下讲,我们就实现用户的文章录入的功能。下讲再见👋

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,907评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,546评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,705评论 0 238
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,624评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,940评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,371评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,672评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,396评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,069评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,350评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,876评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,243评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,847评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,004评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,755评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,378评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,266评论 2 259

推荐阅读更多精彩内容