会话控制
用户登录,技术上讲是叫会话控制。
HTTP 是无状态的,要保证会话控制,要利用 Cookie 来做。
一般做会话控制,有两种方式:
- 一种是不带后端存储
- 另一种是带后端存储
三方库地址:gorilla/sessions
安装
$ go get github.com/gorilla/sessions
gorilla/sessions 库
gorilla/sessions 原生支持 Cookie 会话和文件会话两种方式,也有很多第三方的存储器支持,MySQL/Memcache/Redis 应有尽有。这里记录一下 Cookie 会话,其他会话存储器的使用大同小异,只是初始化时有所不同。
gorilla/sessions 库为我们做了什么
gorilla/sessions 为我们提供了会话数据的加密解密,以及底层的 Cookie 管理。使用时,我们可以通过配置信息来更改其默认行为。
我们需要做什么
gorilla/sessions 提供的接口比较简单,为了后续方便维护,我们将其进行了简单的封装:
package auth
import (
"GoBlog/app/models/user"
"GoBlog/pkg/session"
"errors"
"gorm.io/gorm"
)
// _getUID 获取当前用户的UID 如果不存在则返回空
func _getUID() string {
_uid := session.Get("uid")
uid, ok := _uid.(string)
if ok && len(uid) > 0 {
return uid
}
return ""
}
// User 获取登录用户信息
func User() user.User {
uid := _getUID()
if len(uid) > 0 {
_user, err := user.Get(uid)
if err != nil {
return _user
}
}
return user.User{}
}
// Attempt 尝试登录
func Attempt(email string, password string) error {
// 1. 根据 Email 获取用户
_user, err := user.GetByEmail(email)
// 2. 如果出现错误
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return errors.New("账号不存在或密码错误")
}
return errors.New("内部错误,请稍后再试")
}
// 3. 匹配密码
if !_user.ComparePassword(password) {
return errors.New("账号不存在或密码错误")
}
// 4. 登录用户,保存会话
session.Put("uid", _user.GetStringID())
return nil
}
// Login 登录指定用户
func Login(_user user.User) {
session.Put("uid", _user.GetStringID())
}
// Logout 退出用户
func Logout() {
session.Forget("uid")
}
// Check 检测是否登录
func Check() bool {
return len(_getUID()) > 0
}
评论前必须登录!
注册