GoFrame登錄實戰之session實現
一、概念介紹
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.toml
│
├─gession
│ └─default
│ C1YHTZWK7PS0AEN9VA
│
├─template
│ index.html
│ user_index.html
│
└─test
test.http
main.go
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
"github.com/gogf/gf/os/gsession"
)
const SessionUser = "SessionUser"
func main() {
s := g.Server()
// 設置存儲方式
sessionStorage := g.Config().GetString("SessionStorage")
if sessionStorage == "redis" {
s.SetConfigWithMap(g.Map{
"SessionIdName": g.Config().GetString("server.SessionIdName"),
"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.GetString("username")
password := r.GetString("password")
//dbUsername := "admin"
//dbPassword := "123456"
dbUsername := g.Config().GetString("username")
dbPassword := g.Config().GetString("password")
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 r.Session.Contains(SessionUser) {
r.Middleware.Next()
} else {
// 獲取用錯誤碼
r.Response.WriteJson(g.Map{
"code": 403,
"msg": "您訪問超時或已登出",
})
}
}
config.toml
# 賬號
username = "admin"
# 密碼
password = "123456"
# session存儲方式file,memory,redis
# SessionStorage = "file"
[server]
Address = ":8199"
SessionIdName = "gSessionId"
SessionPath = "./gession"
SessionMaxAge = "1m"
DumpRouterMap = true
# 模板引擎配置
[viewer]
Path = "template"
DefaultFile = "index.html"
Delimiters = ["${", "}"]
index.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="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/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>
user_index.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/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>
test.http
POST http://127.0.0.1:8199/user/list
#Cookie: MySessionId=C1YHEOJ167MSBFJ5K1
###
視頻地址
- 騰訊課堂教程地址:https://ke.qq.com/course/2587868?taid=9171133864049884&tuin=13b4f9bd
- bilibili教程地址:https://www.bilibili.com/video/BV1oT4y1G7ge/
代碼地址
- github:https://github.com/goflyfox/gfstudy
- gitee:https://gitee.com/goflyfox/gfstudy
- 公衆號搜索:GoWeb學習之路