[ADD]用户登陆
This commit is contained in:
parent
47726bea75
commit
2907760207
|
@ -1,25 +1,101 @@
|
||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
"log"
|
"liteblog/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const SESSION_USER_KEY = "SESSION_USER_KEY"
|
||||||
|
|
||||||
type NestPreparer interface {
|
type NestPreparer interface {
|
||||||
NestPrepare()
|
NestPrepare()
|
||||||
}
|
}
|
||||||
|
|
||||||
type BaseController struct {
|
type BaseController struct {
|
||||||
beego.Controller
|
beego.Controller
|
||||||
|
IsLogin bool // 标识 用户是否登陆
|
||||||
|
User models.User // 登陆的用户
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *BaseController) Prepare() {
|
func (ctx *BaseController) Prepare() {
|
||||||
log.Println("BaseController")
|
|
||||||
// 判断子类是否实现了NestPreparer接口,如果实现了就调用接口方法。
|
|
||||||
// 将页面路径保存到path变量中
|
// 将页面路径保存到path变量中
|
||||||
ctx.Data["Path"] = ctx.Ctx.Request.RequestURI
|
ctx.Data["Path"] = ctx.Ctx.Request.RequestURI
|
||||||
ctx.Data["Username"] = "xxxx"
|
// 记录登陆的状态
|
||||||
|
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
|
||||||
|
|
||||||
if app, ok := ctx.AppController.(NestPreparer); ok {
|
if app, ok := ctx.AppController.(NestPreparer); ok {
|
||||||
app.NestPrepare()
|
app.NestPrepare()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
//func (ctx *BaseController) MustLogin() {
|
||||||
|
// if !ctx.IsLogin {
|
||||||
|
// ctx.Abort500(syserrors.NoUserError{})
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
func (ctx *BaseController) GetMustString(key string, msg string) string {
|
||||||
|
KeyString := ctx.GetString(key, "")
|
||||||
|
if len(KeyString) == 0 {
|
||||||
|
ctx.Abort500(errors.New(msg))
|
||||||
|
}
|
||||||
|
return KeyString
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *BaseController) Abort500(err error) {
|
||||||
|
ctx.Data["Error"] = err
|
||||||
|
ctx.Abort("500")
|
||||||
|
}
|
||||||
|
|
||||||
|
type H map[string]interface{}
|
||||||
|
|
||||||
|
type ResultJsonValue struct {
|
||||||
|
Code int `json:"code"`
|
||||||
|
Msg string `json:"msg"`
|
||||||
|
Action string `json:"action,omitempty"`
|
||||||
|
Count int `json:"count,omitempty"`
|
||||||
|
Data interface{} `json:"data,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *BaseController) JSONOk(msg string, actions ...string) {
|
||||||
|
var action string
|
||||||
|
if len(actions) > 0 {
|
||||||
|
action = actions[0]
|
||||||
|
}
|
||||||
|
ctx.Data["json"] = &ResultJsonValue{
|
||||||
|
Code: 0,
|
||||||
|
Msg: msg,
|
||||||
|
Action: action,
|
||||||
|
}
|
||||||
|
ctx.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *BaseController) JSONOkH(msg string, maps H) {
|
||||||
|
if maps == nil {
|
||||||
|
maps = H{}
|
||||||
|
}
|
||||||
|
maps["code"] = 0
|
||||||
|
maps["msg"] = msg
|
||||||
|
ctx.Data["json"] = maps
|
||||||
|
ctx.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *BaseController) JSONOkData(count int, data interface{}) {
|
||||||
|
ctx.Data["json"] = &ResultJsonValue{
|
||||||
|
Code: 0,
|
||||||
|
Count: count,
|
||||||
|
Msg: "成功!",
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
ctx.ServeJSON()
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"liteblog/models"
|
||||||
|
"liteblog/syserrors"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserController struct {
|
||||||
|
BaseController
|
||||||
|
}
|
||||||
|
|
||||||
|
// 登陆页面
|
||||||
|
// @router /login [get]
|
||||||
|
func (c *UserController) Login() {
|
||||||
|
c.TplName = "login.html"
|
||||||
|
}
|
||||||
|
|
||||||
|
// @router /signin [post]
|
||||||
|
func (c *UserController) SignIn() {
|
||||||
|
log.Print("======")
|
||||||
|
// 判断邮箱不能为空
|
||||||
|
email := c.GetMustString("email", "邮箱不能为空")
|
||||||
|
// 判断密码不能为空
|
||||||
|
password := c.GetMustString("password", "密码不能为空")
|
||||||
|
|
||||||
|
var (
|
||||||
|
user models.User
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
if user, err = models.QueryUserByEmailAndPassword(email, password); err != nil {
|
||||||
|
c.Abort500(syserrors.NewError("邮箱或密码不对", err))
|
||||||
|
}
|
||||||
|
// 将user保存到session
|
||||||
|
c.SetSession(SESSION_USER_KEY, user)
|
||||||
|
c.JSONOk("登陆成功", "/")
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
13
main.go
13
main.go
|
@ -1,7 +1,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/gob"
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
|
"liteblog/models"
|
||||||
_ "liteblog/routers"
|
_ "liteblog/routers"
|
||||||
_ "liteblog/models"
|
_ "liteblog/models"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -9,6 +11,7 @@ import (
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
initTemplate()
|
initTemplate()
|
||||||
|
initSession()
|
||||||
beego.Run()
|
beego.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,5 +23,15 @@ func initTemplate() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,9 @@ import (
|
||||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
var db = initDbConnect()
|
||||||
db := initDbConnect()
|
|
||||||
|
func init() {
|
||||||
//SetMaxOpenConns用于设置最大打开的连接数
|
//SetMaxOpenConns用于设置最大打开的连接数
|
||||||
//SetMaxIdleConns用于设置闲置的连接数
|
//SetMaxIdleConns用于设置闲置的连接数
|
||||||
db.DB().SetMaxIdleConns(10)
|
db.DB().SetMaxIdleConns(10)
|
||||||
|
@ -39,6 +40,7 @@ func init() {
|
||||||
Role: 0,
|
Role: 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func initDbConnect() *gorm.DB {
|
func initDbConnect() *gorm.DB {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import "github.com/jinzhu/gorm"
|
import (
|
||||||
|
"github.com/jinzhu/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
|
@ -9,4 +11,9 @@ type User struct {
|
||||||
Avatar string
|
Avatar string
|
||||||
Pwd string
|
Pwd string
|
||||||
Role int `gorm:"default:1"` // 0 管理员 1正常用户
|
Role int `gorm:"default:1"` // 0 管理员 1正常用户
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func QueryUserByEmailAndPassword(email, password string) (user User, err error) {
|
||||||
|
e := db.Model(&User{}).First(&user, "email = ? and pwd = ?", email, password).Error
|
||||||
|
return user, e
|
||||||
|
}
|
||||||
|
|
|
@ -8,5 +8,7 @@ import (
|
||||||
func init() {
|
func init() {
|
||||||
//beego.Router("/", &controllers.IndexController{})
|
//beego.Router("/", &controllers.IndexController{})
|
||||||
beego.ErrorController(&controllers.ErrorController{})
|
beego.ErrorController(&controllers.ErrorController{})
|
||||||
beego.Include(&controllers.IndexController{})
|
beego.Include(
|
||||||
|
&controllers.IndexController{},
|
||||||
|
&controllers.UserController{})
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
/**
|
||||||
|
@Name:layui.sysn
|
||||||
|
*/
|
||||||
|
layui.define(['jquery', 'layer'], function (exports) {
|
||||||
|
var $ = layui.jquery,
|
||||||
|
layer = layui.layer,
|
||||||
|
ajaxObj = {},
|
||||||
|
sysn = {};
|
||||||
|
|
||||||
|
function ajax(url, type, timeout, data, success, error, complete) {
|
||||||
|
var error2 = function (ret) {
|
||||||
|
var msg = ret.responseText || ret.msg||ret;
|
||||||
|
if (ret.status != undefined && ret.status == 0) {
|
||||||
|
msg = "网络异常";
|
||||||
|
}
|
||||||
|
if (!error) {
|
||||||
|
sysn.sayError(msg);
|
||||||
|
} else {
|
||||||
|
error(msg)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$.ajax({
|
||||||
|
url: url,
|
||||||
|
type: type,
|
||||||
|
timeout: timeout || 5000,
|
||||||
|
data: data,
|
||||||
|
success: function (ret) {
|
||||||
|
if (ret.code == 0) {
|
||||||
|
success(ret)
|
||||||
|
} else {
|
||||||
|
error2(ret)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: error2,
|
||||||
|
complete: complete
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sysn.get = function (url, data) {
|
||||||
|
ajaxObj.url = url;
|
||||||
|
ajaxObj.data = data;
|
||||||
|
ajaxObj.method = "GET";
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
sysn.post = function (url, data) {
|
||||||
|
ajaxObj.url = url;
|
||||||
|
ajaxObj.data = data;
|
||||||
|
ajaxObj.method = "POST";
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
sysn.success = function (success) {
|
||||||
|
ajaxObj.success = success;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
sysn.error = function (error) {
|
||||||
|
ajaxObj.error = error;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
sysn.complete = function (complete) {
|
||||||
|
ajaxObj.complete = complete;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
sysn.run = function () {
|
||||||
|
ajax(ajaxObj.url, ajaxObj.method, ajaxObj.timeout, ajaxObj.data, ajaxObj.success, ajaxObj.error, ajaxObj.complete);
|
||||||
|
};
|
||||||
|
|
||||||
|
sysn.sayOk = function (msg) {
|
||||||
|
layer.msg(msg, {icon: 6});
|
||||||
|
};
|
||||||
|
sysn.sayError = function (msg) {
|
||||||
|
layer.msg(msg, {icon: 5})
|
||||||
|
};
|
||||||
|
|
||||||
|
sysn.setTimeout = function (timeout) {
|
||||||
|
ajaxObj.timeout = timeout;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
//输出test接口
|
||||||
|
exports('sysn', sysn);
|
||||||
|
});
|
|
@ -0,0 +1,14 @@
|
||||||
|
package syserrors
|
||||||
|
|
||||||
|
type Error interface {
|
||||||
|
Error() string
|
||||||
|
Code() int
|
||||||
|
ReasonError() error
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewError(msg string, err2 error) UnKnowError {
|
||||||
|
err := UnKnowError{}
|
||||||
|
err.msg = msg
|
||||||
|
err.reason = err2
|
||||||
|
return err
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package syserrors
|
||||||
|
|
||||||
|
type UnKnowError struct {
|
||||||
|
msg string
|
||||||
|
reason error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err UnKnowError) Error() string {
|
||||||
|
if len(err.msg) == 0 {
|
||||||
|
return "未知错误"
|
||||||
|
} else {
|
||||||
|
return err.msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err UnKnowError) Code() int {
|
||||||
|
return 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err UnKnowError) ReasonError() error {
|
||||||
|
return err.reason
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>关于-闲言轻博客</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
{{ template "shares/link.html". }}
|
||||||
|
<style>
|
||||||
|
.layui-form-label {
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
.layui-input-block {
|
||||||
|
margin-left: 80px;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 450px) {
|
||||||
|
.layui-form-item .layui-input-inline {
|
||||||
|
margin: 0 0 10px 80px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="lay-blog">
|
||||||
|
{{ template "shares/header.html". }}
|
||||||
|
<div class="container-wrap">
|
||||||
|
<div class="container container-message container-details container-about">
|
||||||
|
<div class="contar-wrap">
|
||||||
|
<div class="item">
|
||||||
|
<div class="item-box">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ template "shares/footer.html". }}
|
||||||
|
<script>
|
||||||
|
layui.use(['form', 'jquery', 'layer', 'sysn'], function () {
|
||||||
|
var form = layui.form,
|
||||||
|
sysn = layui.sysn,
|
||||||
|
$ = layui.jquery,
|
||||||
|
layer = layui.layer;
|
||||||
|
//监听提交
|
||||||
|
form.on('submit(login)', function (formData) {
|
||||||
|
sysn.post("/signin", formData.field)
|
||||||
|
// .setTimeout(5000)
|
||||||
|
.success(function (data) {
|
||||||
|
layer.msg(data.msg);
|
||||||
|
if (data.action) {
|
||||||
|
setTimeout(function () {
|
||||||
|
window.location.href = data.action;
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
}).run();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,61 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>关于-闲言轻博客</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
{{ template "shares/link.html". }}
|
||||||
|
</head>
|
||||||
|
<body class="lay-blog">
|
||||||
|
{{ template "shares/header.html". }}
|
||||||
|
<div class="container-wrap">
|
||||||
|
<div class="container container-message container-details container-about">
|
||||||
|
<div class="contar-wrap">
|
||||||
|
<div class="item">
|
||||||
|
<div class="item-box">
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ template "shares/footer.html". }}
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue