beego開(kāi)發(fā)輕博客——第四講 用戶登陸和注冊(cè)

【小雞創(chuàng)作】beego開(kāi)發(fā)輕博客

本章目標(biāo):添加用戶登陸及注冊(cè)功能葡盗!
github: 打開(kāi)后缘屹,點(diǎn)擊右上角star按鈕
視頻教程: B站地址


初始化數(shù)據(jù)-數(shù)據(jù)庫(kù)選用sqlite3數(shù)據(jù)庫(kù)

  1. 安裝 gorm框架 點(diǎn)我進(jìn)入官方文檔
go get -u github.com/jinzhu/gorm
  1. 創(chuàng)建 models->core.go 初始化gorm
import (
    "github.com/jinzhu/gorm"
     //引入sqlite3的驅(qū)動(dòng)
    _ "github.com/jinzhu/gorm/dialects/sqlite"
    "os"
)
var (
     //定義db變量似炎,變量名開(kāi)頭是小寫(xiě),只能同包下訪問(wèn)
    db gorm.DB
)
func init() {
    // 創(chuàng)建data目錄,0777代表文件權(quán)限
    if err := os.MkdirAll("data", 0777); err != nil {
        panic("failed to connect database," + err.Error())
    }
    //打開(kāi)數(shù)據(jù)庫(kù)棱诱,并復(fù)制給db變量瘦陈,data/data.db數(shù)據(jù)文件路徑
    db, err := gorm.Open("sqlite3", "data/data.db")
   //存在錯(cuò)誤,則程序退出岁疼,panic是類似于java的RuntimeException錯(cuò)誤
    if err != nil {
        panic("failed to connect database")
    }
}
  1. 在main.go調(diào)用 core.go的init方法
import (
    // 運(yùn)行main方法之前 調(diào)用models包下的文件的init方法阔涉。先初始化數(shù)據(jù)庫(kù)
    _ "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自動(dòng)同步 用戶表結(jié)構(gòu),只需在models-core.go init方法后面添加如下代碼
func init(){
    ......
    // 自動(dòng)同步表結(jié)構(gòu)
    db.AutoMigrate(&User{})
}
  1. 程序啟動(dòng)的時(shí)候默認(rèn)插入admin用戶字逗,即修改models->core.go文件京郑,在init的方法結(jié)尾,判斷用戶是否存在記錄葫掉,不存在就插入admin用戶些举。
func init(){
    ......
    // 自動(dòng)同步表結(jié)構(gòu)
    db.AutoMigrate(&User{})
    var count int
    // Model(&User{})查詢用戶表, Count(&count) 將用戶表的數(shù)據(jù)賦值給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 框架沒(méi)有用戶登陸與注冊(cè)界面

  1. 新增用戶頁(yè)面:views->user.html點(diǎn)我查詢頁(yè)面代碼
    用戶登陸界面效果
  2. 新增用戶注冊(cè)也頁(yè)面 views->reg.html點(diǎn)我查詢頁(yè)面代碼
    用戶注冊(cè)頁(yè)面效果

啟用beego的session功能

  1. 修改main.go俭厚,開(kāi)啟beego的session功能
func main() {
    initSession()
    ...
}
func initSession() {
    //beego的session序列號(hào)是用gob的方式户魏,因此需要將注冊(cè)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功能,每次請(qǐng)求的時(shí)候都去判斷用戶是否登陸挪挤。并將登陸的信息保存到BaseController控制器里,修改controllers->base.go 文件
//定義session中的key值
const SESSION_USER_KEY = "SESSION_USER_KEY"
...
type BaseController struct {
    beego.Controller
    IsLogin bool //標(biāo)識(shí) 用戶是否登陸
    User    models.User //登陸的用戶
}
func (ctx *BaseController) Prepare() {
    // 驗(yàn)證用戶是否登陸叼丑,判斷session中是否存在用戶,存在就已經(jīng)登陸扛门,不存在就沒(méi)有登陸鸠信。
    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
    ...
}

用戶登陸功能實(shí)現(xiàn)

  1. 首先咱們判斷用戶是否存在,需要到數(shù)據(jù)庫(kù)论寨,更具用戶名和密碼查詢用戶星立,如果能查到就存在,反之不存在政基。因此新增根據(jù)用戶郵箱和密碼查詢用戶的方法贞铣,修改models->user.go,添加下面代碼
func QueryUserByEmailAndPassword(email, password string) (user User, err error) {
    // 這就是gorm的魅力,一句代碼即可沮明,對(duì)開(kāi)發(fā)友好。
    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里面定義的窍奋,第一個(gè)參數(shù)獲取請(qǐng)求的參數(shù)的鍵值對(duì)的key荐健,請(qǐng)求后酱畅,如key對(duì)于的value是空,就返回第二個(gè)參數(shù)*/
    // 判斷郵箱不能為空
    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里面定義的址否,使對(duì)beego的ctx.Abort(..)的封裝餐蔬,目的:優(yōu)化錯(cuò)誤提示。   
      c.Abort500(syserrors.NewError("郵箱或密碼不對(duì)", err))
    }
    //將user保存到session
    c.SetSession(SESSION_USER_KEY, user)
    //JSONOk使在BaseController里面定義的佑附,使對(duì)beego的ctx.ServeJSON()的封裝樊诺,目的:優(yōu)化提示
    //這里將返回 {code: 0, msg: "登陸成功", action: "/"}
    c.JSONOk("登陸成功", "/")
}
  1. 上面咱們定義好的登陸邏輯,現(xiàn)在我們還需要定義beego的路由音同。我們使用beego的注解路由词爬,只需要修改 routers->router.go 文件添加下面一段代碼
func init() {
    ...
    beego.Include(
        &controllers.IndexController{},
        &controllers.UserController{},
    )
    ...
}
  1. 咱們用戶登陸的后臺(tái)業(yè)務(wù)已經(jīng)完成,現(xiàn)在開(kāi)始修改前臺(tái)頁(yè)面权均,使能夠登陸成功顿膨。前臺(tái)頁(yè)面user.html頁(yè)面已經(jīng)新增,其核心代碼:
<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="請(qǐng)輸入郵箱" 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="請(qǐng)輸入密碼"
                                       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">注冊(cè)用戶</a>
               </div>
          </div>
</form>

咱們要實(shí)現(xiàn)這個(gè)form表單的提交邏輯叽赊,讓其和后臺(tái)打通恋沃,修改static->js->blog.js 。其中sysn是對(duì)jquery的ajax請(qǐng)求方法的進(jìn)一步封裝查看代碼

    // 
    //登陸
    form.on('submit(login)', function (fromdata) {
        //發(fā)送ajax請(qǐng)求
        sysn.post("/login", fromdata.field)
             // 設(shè)置登陸成功回掉函數(shù)
            .success(function (data) {
                // 提示
                layer.msg(data.msg);
                // 后臺(tái)如果返回有action 必指,就是跳轉(zhuǎn)到新頁(yè)面芽唇。
                if (data.action) {
                    setTimeout(function () {
                        window.location.href = data.action;
                    }, 300)
                }
            }).run();
        return false;
    });

用戶登陸已經(jīng)完成。

用戶注冊(cè)功能實(shí)現(xiàn)

1. 數(shù)據(jù)庫(kù)調(diào)整

1.1 由于郵箱和昵稱不能重復(fù)取劫,因此匆笤,我們需要新增能夠根據(jù)用戶昵稱查詢用戶和根據(jù)用戶郵箱查詢用戶的方法。用來(lái)查詢數(shù)據(jù)是否存在谱邪。代碼如下
//根據(jù)昵稱查用戶
func  QueryUserByName(name string) (user User, err error) {
    return user, db.db.Where("name = ?", name).Take(&user).Error
}
//根據(jù)郵箱查用戶
func QueryUserByEmail(email string) (user User, err error) {
    return user, db.db.Where("email = ?", email).Take(&user).Error
}
1.2 除了判斷重復(fù)的問(wèn)題炮捧,最重要的我們還需要提供一個(gè)保存用戶的方法。代碼如下
//   保存用戶
func SaveUser(user *User) error {
    return db.Create(user).Error
}

2. 控制器UserController調(diào)整

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", "確認(rèn)密碼不能為空书蚪!")
    if strings.Compare(pwd1, pwd2) != 0 {
        c.Abort500(errors.New("密碼與確認(rèn)密碼 必須要一致!"))
    }
    if u, err := models.QueryUserByName(name); err == nil &&  u.ID != 0 {
        c.Abort500(syserrors.NewError("用戶昵稱已經(jīng)存在!", err))
    }
    if u, err := models.QueryUserByEmail(email); err == nil && u.ID != 0 {
        c.Abort500(syserrors.NewError("用戶郵箱已經(jīng)存在迅栅!", err))
    }
    //開(kāi)始保存用戶
    if err := models.SaveUser(&models.User{
        Name:   name,
        Email:  email,
        Pwd:    pwd1,
        Avatar: "",
        Role:   1,
    }); err != nil {
        c.Abort500(syserrors.NewError("用戶注冊(cè)失敗", err))
    }
    c.JSONOk("注冊(cè)成功", "/user")
}

3.修改前臺(tái)代碼

3.1 注冊(cè)頁(yè)面的核心代碼:
<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="請(qǐng)輸入用戶名" 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="請(qǐng)輸入郵箱" 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="請(qǐng)輸入密碼"
                    autocomplete="off" class="layui-input">
        </div>
    </div>
    <div class="layui-form-item">
        <label class="layui-form-label">確認(rèn)密碼</label>
        <div class="layui-input-inline">
            <input type="password2" name="password2" required lay-verify="required"
                    placeholder="請(qǐng)輸入密碼"
                    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">注冊(cè)</button>
            <button type="reset" class="layui-btn layui-btn-primary">重置</button>
        </div>
    </div>
</form>
3.2 修改static->js->blog.js 代碼如下
//注冊(cè)
    form.on('submit(reg)', function (fromdata) {
        sysn.post("/reg", fromdata.field)
            .success(function (data) {
                // 設(shè)置登陸成功回掉函數(shù)
                layer.msg(data.msg);
                // 后臺(tái)如果返回有action 殊校,就是跳轉(zhuǎn)到新頁(yè)面。
                if (data.action) {
                    setTimeout(function () {
                        window.location.href = data.action;
                    }, 300)
                }
            }).run();
        return false;
    });

用戶注冊(cè)功能完成


總結(jié)

本講读存,我們實(shí)現(xiàn)了登陸和注冊(cè)兩個(gè)功能为流。我們程序的大概流程是:頁(yè)面發(fā)送請(qǐng)求 呕屎,beego接收請(qǐng)求,匹配咱們定義好的路由敬察,調(diào)用對(duì)應(yīng)的controller方法秀睛,再由controller的方法去查數(shù)據(jù)庫(kù),做一些業(yè)務(wù)的處理莲祸,返回結(jié)果給頁(yè)面蹂安。我們主要定義好 路由規(guī)則(beego的Router)、核心業(yè)務(wù)邏輯(beego的Controller)锐帜、數(shù)據(jù)庫(kù)操作的方法田盈,即可。
下講抹估,我們就實(shí)現(xiàn)用戶的文章錄入的功能缠黍。下講再見(jiàn)??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市药蜻,隨后出現(xiàn)的幾起案子瓷式,更是在濱河造成了極大的恐慌,老刑警劉巖语泽,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贸典,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡踱卵,警方通過(guò)查閱死者的電腦和手機(jī)廊驼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)惋砂,“玉大人妒挎,你說(shuō)我怎么就攤上這事∥鞫” “怎么了酝掩?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)眷柔。 經(jīng)常有香客問(wèn)我期虾,道長(zhǎng),這世上最難降的妖魔是什么驯嘱? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任镶苞,我火速辦了婚禮,結(jié)果婚禮上鞠评,老公的妹妹穿的比我還像新娘茂蚓。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布煌贴。 她就那樣靜靜地躺著御板,像睡著了一般锥忿。 火紅的嫁衣襯著肌膚如雪牛郑。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天敬鬓,我揣著相機(jī)與錄音淹朋,去河邊找鬼。 笑死钉答,一個(gè)胖子當(dāng)著我的面吹牛础芍,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播数尿,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼仑性,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了右蹦?” 一聲冷哼從身側(cè)響起诊杆,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎何陆,沒(méi)想到半個(gè)月后晨汹,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贷盲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年淘这,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片巩剖。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡铝穷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出佳魔,到底是詐尸還是另有隱情曙聂,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布吃引,位于F島的核電站筹陵,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏镊尺。R本人自食惡果不足惜朦佩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望庐氮。 院中可真熱鬧语稠,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至慨畸,卻和暖如春莱坎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背寸士。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工檐什, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人弱卡。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓乃正,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親婶博。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瓮具,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容