1 Star 0 Fork 25

zhiyubujian / gfstudy

forked from goflyfox / gfstudy 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
14.GoFrame登录实战之session实现.md 9.13 KB
一键复制 编辑 原始数据 按行查看 历史
zcool321@sina.com 提交于 2020-04-19 02:10 . update gsession doc

GoFrame登录实战之session实现

一、概念介绍

GF框架提供了完善的Session管理能力,由gsession模块实现。由于Session机制在HTTP服务中最常用,因此后续章节中将着重以HTTP服务为示例介绍Session的使用。

二、存储实现方式

gsession实现并为开发者提供了常见的三种Session存储实现方式:

  1. 基于文件存储(默认):单节点部署方式下比较高效的持久化存储方式;
  2. 基于纯内存存储:性能最高效,但是无法持久化保存,重启即丢失;
  3. 基于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

###
1
https://gitee.com/fenglingyouyou/gfstudy.git
git@gitee.com:fenglingyouyou/gfstudy.git
fenglingyouyou
gfstudy
gfstudy
master

搜索帮助