GF
框架提供了完善的Session
管理能力,由gsession
模块实现。由于Session
机制在HTTP
服务中最常用,因此后续章节中将着重以HTTP
服务为示例介绍Session
的使用。
gsession
实现并为开发者提供了常见的三种Session
存储实现方式:
- 基于文件存储(默认):单节点部署方式下比较高效的持久化存储方式;
- 基于纯内存存储:性能最高效,但是无法持久化保存,重启即丢失;
- 基于
Redis
存储:远程Redis
节点存储Session
数据,支持应用多节点部署;
代码:
s := g.Server()
// 设置文件
s.SetConfigWithMap(g.Map{
"SessionStorage": gsession.NewStorageFile("/tmp"),
})
// 设置内存
s.SetConfigWithMap(g.Map{
"SessionStorage": gsession.NewStorageMemory(),
})
// 设置redis
s.SetConfigWithMap(g.Map{
"SessionStorage": gsession.NewStorageRedis(g.Redis()),
})
:.
│ go.mod
│ go.sum
│ main.go
│
├─config
│ config.yaml
│
├─gession
│ └─default
│ C1YHTZWK7PS0AEN9VA
│
├─template
│ index.html
│ user_index.html
│
└─test
test.http
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/gsession"
)
const SessionUser = "SessionUser"
func main() {
s := g.Server()
// 设置存储方式
sessionStorage := g.Config().MustGet(gctx.New(), "SessionStorage").String()
if sessionStorage == "redis" {
s.SetConfigWithMap(g.Map{
"SessionIdName": g.Config().MustGet(gctx.New(), "server.SessionIdName").String(),
"SessionStorage": gsession.NewStorageRedis(g.Redis()),
})
} else if sessionStorage == "memory" {
s.SetConfigWithMap(g.Map{
"SessionStorage": gsession.NewStorageMemory(),
})
}
// 常规注册
group := s.Group("/")
group.GET("/", func(r *ghttp.Request) {
r.Response.WriteTpl("index.html", g.Map{
"title": "登录页面",
})
})
group.POST("/login", func(r *ghttp.Request) {
username := r.Get("username").String()
password := r.Get("password").String()
//dbUsername := "admin"
//dbPassword := "123456"
dbUsername := g.Config().MustGet(r.GetCtx(), "username").String()
dbPassword := g.Config().MustGet(r.GetCtx(), "password").String()
if username == dbUsername && password == dbPassword {
// 添加session
r.Session.Set(SessionUser, g.Map{
"username": dbUsername,
"name": "管理员",
})
r.Response.WriteJson(g.Map{
"code": 0,
"msg": "登录成功",
})
r.Exit()
}
r.Response.WriteJson(g.Map{
"code": -1,
"msg": "登录失败",
})
})
// 用户组
userGroup := s.Group("/user")
userGroup.Middleware(MiddlewareAuth)
// 列表页面
userGroup.GET("/index", func(r *ghttp.Request) {
r.Response.WriteTpl("user_index.html", g.Map{
"title": "列表页面",
"dataList": g.List{
g.Map{
"date": "2020-04-01",
"name": "朱元璋",
"address": "江苏110号",
},
g.Map{
"date": "2020-04-02",
"name": "徐达",
"address": "江苏111号",
},
g.Map{
"date": "2020-04-03",
"name": "李善长",
"address": "江苏112号",
},
}})
})
userGroup.POST("/logout", func(r *ghttp.Request) {
// 删除session
r.Session.Remove(SessionUser)
r.Response.WriteJson(g.Map{
"code": 0,
"msg": "登出成功",
})
})
s.Run()
}
// 认证中间件
func MiddlewareAuth(r *ghttp.Request) {
if ok, _ := r.Session.Contains(SessionUser); ok {
r.Middleware.Next()
} else {
// 获取用错误码
r.Response.WriteJson(g.Map{
"code": 403,
"msg": "您访问超时或已登出",
})
}
}
username: admin # 账号
password: "123456" # 密码
# session存储方式file,memory,redis
# SessionStorage = "redis"
server:
Address: :80
SessionIdName: gSessionId
SessionPath: ./gession
SessionMaxAge: 1m
DumpRouterMap: true
viewer: # 模板引擎配置
Path: template
DefaultFile: index.html
Delimiters:
- ${
- "}"
redis: # Redis数据库配置
default: 192.168.31.128:6379,0
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<style>
.el-row {
margin-bottom: 20px;
}
</style>
</head>
<body>
<div id="app">
<el-row>
<el-col :span="6" :offset="6" style="text-align: center">
<span>${ .title }</span>
</el-col>
</el-row>
<el-row>
<el-col :span="6" :offset="6">
<el-input v-model="username" placeholder="请输入内容"></el-input>
</el-col>
</el-row>
<el-row>
<el-col :span="6" :offset="6">
<el-input placeholder="请输入密码" v-model="password" show-password></el-input>
</el-col>
</el-row>
<el-row>
<el-col :span="6" :offset="6" style="text-align: center">
<el-button @click="login">登录</el-button>
</el-col>
</el-row>
</div>
</body>
<!-- import Vue before Element -->
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<!-- import JavaScript -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
<script>
new Vue({
el: '#app',
data: function () {
return {
visible: false,
username: '',
password: ''
}
},
methods: {
login: function () {
axios.post('/login', { // 还可以直接把参数拼接在url后边
username: this.username,
password: this.password
}).then(function (res) {
console.log(res.data)
if (res.data.code == 0) {
alert(res.data.msg)
window.location.href = "/user/index"
} else {
alert("失败:" + res.data.msg)
}
}).catch(function (error) {
console.log(error);
});
}
}
})
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<style>
.el-row {
margin-bottom: 20px;
}
</style>
</head>
<body>
<div id="app">
<el-row>
<el-col :span="6" :offset="6" style="text-align: center">
<span>${ .title }</span>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<template>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
</template>
</el-col>
</el-row>
<el-row>
<el-col :span="6" :offset="6" style="text-align: center">
<el-button @click="logout">登出</el-button>
</el-col>
</el-row>
</div>
</body>
<!-- import Vue before Element -->
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<!-- import JavaScript -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
<script>
${/*
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}]
*/}
var listData = new Array();
var data;
${range $index, $elem := .dataList}
data = {};
${range $key, $value := $elem}
data['${$key}'] = '${$value}'
${end}
listData.push(data)
${end}
var vm = new Vue({
el: '#app',
data: {
visible: false,
tableData: listData
},
methods: {
logout: function () {
axios.post('/user/logout', {}).then(function (res) {
console.log(res.data)
if (res.data.code == 0) {
alert(res.data.msg)
window.location.href = "/"
} else {
alert("失败:" + res.data.msg)
}
}).catch(function (error) {
console.log(error);
});
}
},
mounted: function () {
}
})
</script>
</html>
GET http://127.0.0.1/user/index
Cookie: gSessionId=C24J0ONC99ECJPEWBE
###