我们希望用户登录后可以有写博客的功能,当然也允许用户退出。实现该功能的操作需要使用session。
如果用户没有登录,直接访问首页,只可以查看文章,标签,相册等,但是没有写博客的功能:
一、Controller
首先我们在登录的时候添加session。
先修改配置文件打开session,打开conf包下的app.conf文件,添加一行:
appname = myblog
httpport = 8080
runmode = dev
sessionon = true
或者在main.go中打开session:
func main() {
utils.InitMysql()
beego.BConfig.WebConfig.Session.SessionOn = true // 打开session
beego.Run()
}
以上两个操作,选择一个即可。
然后修改登录的Post方法,在登录的时候,我们设置session:
func (this *LoginController) Post() {
...
if id > 0 {
/*
设置了session后悔将数据处理设置到cookie,然后再浏览器进行网络请求的时候回自动带上cookie
因为我们可以通过获取这个cookie来判断用户是谁,这里我们使用的是session的方式进行设置
*/
this.SetSession("loginuser", username)
this.Data["json"] = map[string]interface{}{"code": 1, "message": "登录成功"}
} else {
this.Data["json"] = map[string]interface{}{"code": 0, "message": "登录失败"}
}
this.ServeJSON()
}
接下来,我们新添加一个路由:
func init() {
beego.Router("/", &controllers.HomeController{})
beego.Router("/register", &controllers.RegisterController{})
beego.Router("/login", &controllers.LoginController{})
}
当访问/,这个根路径的时候,我们表示访问首页。
接下来创建一个新的Controller,HomeController,用于控制首页。但是在这之前,我们先设置一个父Controller用于获取session,查看用户是否登录。
先创建一个go文件:base_controller.go
type BaseController struct {
beego.Controller
IsLogin bool
Loginuser interface{}
}
先定义个BaseController,里面额外设置两个字段,IsLogin表示用户是否登录,Loginuser表示用户名。
//判断是否登录
func (this *BaseController) Prepare() {
loginuser := this.GetSession("loginuser")
fmt.Println("loginuser---->", loginuser)
if loginuser != nil {
this.IsLogin = true
this.Loginuser = loginuser
} else {
this.IsLogin = false
}
this.Data["IsLogin"] = this.IsLogin
}
接下类,重写Prepare()方法,用于获取session。
//判断是否登录
func (this *BaseController) Prepare() {
loginuser := this.GetSession("loginuser")
fmt.Println("loginuser---->", loginuser)
if loginuser != nil {
this.IsLogin = true
this.Loginuser = loginuser
} else {
this.IsLogin = false
}
this.Data["IsLogin"] = this.IsLogin
}
这个函数主要是为了用户扩展用的,这个函数会在下面定义的这些 Method 方法之前执行,用户可以重写这个函数实现类似用户验证之类。然后再创建一个home_controller.go文件。
type HomeController struct {
//beego.Controller
BaseController
}
在Get()方法 中,渲染home页面即可。
func (this *HomeController)Get(){
fmt.Println("IsLogin:",this.IsLogin,this.Loginuser)
this.TplName="home.html"
}
二、View
我们需要如下几个功能:
后续的每个页面都有这几个功能。所以我们可以让页面嵌套。
现在views目录下创建一个子目录block,里面创建一个html页面:nav.html,内容如下:
<div id="nav">
<div id="nav-write-article">
<ul>
{{/*如果已经登录,才会显示"写博客"*/}}
{{if .IsLogin}}
<li><a href="/article/add">写博客</a></li>
{{end}}
</ul>
</div>
<div id="nav-menu">
<ul>
<li><a href="/">首页</a></li>
<li><a href="/tags">标签</a></li>
<li><a href="/album">相册</a></li>
<li><a href="/#">关于我</a></li>
</ul>
</div>
<div id="nav-login">
<ul>
{{if .IsLogin}}
<li><a href="">退出</a></li>
{{else}}
<li><a href="/login">登录</a></li>
<li><a href="/register">注册</a></li>
{{end}}
</ul>
</div>
</div>
当然这里需要判断用户是否登录,如果登录,显示写博客功能,以及可以退出。否则显示登录或注册。
接下来,我们创建一个新的页面:home.html,内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
<link href="../static/css/blogsheet.css" rel="stylesheet">
</head>
<body>
{{template "block/nav.html" .}}
</body>
</html>
通过页面的嵌套,我们可以将标签显示到home页面上。
特别注意,{{template "block/nav.html" .}},后面的
.
,这是传递当前参数到子模板
同样,我们将之前的login.html页面和register.html页面,也将nav嵌套进来,代码如下:
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
<link rel="stylesheet" type="text/css" href="../static/css/lib/login.css">
<link rel="stylesheet" type="text/css" href="../static/css/blogsheet.css">
<script src="../static/js/lib/jquery-3.3.1.min.js"></script>
<script src="../static/js/lib/jquery.url.js"></script>
<script src="../static/js/blog.js"></script>
</head>
<body>
<!--
<div id="nav">
<div id="nav-login">
<ul>
<li><a href="/login">登录</a></li>
<li><a href="/register">注册</a></li>
</ul>
</div>
</div>
-->
{{template "block/nav.html"}}
<div class="htmleaf-container">
<div class="wrapper">
{{/*注册表单*/}}
<div class="container">
<h1>Welcome</h1>
<form id="login-form" class="form">
<input type="text" name="username" placeholder="请输入用户名">
<input type="password" name="password" placeholder="请输入密码" id="login-password">
<br>
<button type="submit" id="login-button">登录</button>
</form>
</div>
{{/*背景动画*/}}
<ul class="bg-bubbles">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</div>
</body>
</html>
register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
<link rel="stylesheet" type="text/css" href="../static/css/lib/login.css">
<link rel="stylesheet" type="text/css" href="../static/css/blogsheet.css">
<script src="../static/js/lib/jquery-3.3.1.min.js"></script>
<script src="../static/js/lib/jquery.url.js"></script>
<script src="../static/js/blog.js"></script>
</head>
<body>
<!--
<div id="nav">
<div id="nav-login">
<ul>
<li><a href="/login">登录</a></li>
<li><a href="/register">注册</a></li>
</ul>
</div>
</div>
-->
{{template "block/nav.html"}}
<div class="htmleaf-container">
<div class="wrapper">
{{/*注册表单*/}}
<div class="container">
<h1>Welcome</h1>
<form id="register-form" class="form">
<input type="text" name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password" id="register-password">
<input type="password" name="repassword" placeholder="rePassword">
<br>
<button type="submit" id="login-button">Register</button>
</form>
</div>
{{/*背景动画*/}}
<ul class="bg-bubbles">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</div>
</body>
</html>
三、退出
我们先在nav.html页面中,添加退出的脚本:
<div id="nav-login">
<ul>
{{if .IsLogin}}
<li><a href='javascript:if(confirm("确定退出吗?")){location="/exit"}'>退出</a></li>
{{else}}
<li><a href="/login">登录</a></li>
<li><a href="/register">注册</a></li>
{{end}}
</ul>
</div>
然后重新注册一个路由,用于处理退出:
func init() {
beego.Router("/", &controllers.HomeController{})
//注册
beego.Router("/register", &controllers.RegisterController{})
//登录
beego.Router("/login", &controllers.LoginController{})
//退出
beego.Router("/exit", &controllers.ExitController{})
}
然后再创建一个go文件:exit_controller.go
package controllers
type ExitController struct {
BaseController
}
func (this *ExitController)Get(){
//清除该用户登录状态的数据
this.DelSession("loginuser")
this.Redirect("/",302)
}
清除session后,重定位到/路径上。
四、运行效果
我们重启项目后,打来浏览器输入网址:http://127.0.0.1:8081/
浏览器如下:
服务器端运行如下:
点击退出按钮:
后台程序执行效果:
作者:Davie
出处:千锋教育go语言教研部