gin框架笔记
1、实现http://127.0.0.1:8080/index.html的形式访问前端页面。gin-contrib/static 使用中间件的方式判断是否存在该静态文件。fileserver 是一个 Handler,判断 fs 中是否有请求的文件,如果有则使用 fileserver 将文件写入到 gin 的 writer 里面返回,否则就不处理,中间件处理结束之后就会去匹配对应的 api
//htmlfile为html文件存放的文件夹
r.Use(static.Serve("/", static.LocalFile("./htmlfile/", false)))
2、跨域
方法1、
func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token")
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
c.Header("Access-Control-Allow-Credentials", "true")
//放行所有OPTIONS方法
if method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
}
// 处理请求
c.Next()
}
}
//添加到中间件
r.Use(Cors())
方法2、
import (
"github.com/gin-contrib/cors"
)
corsMiddleWare := cors.Default()
r.Use(corsMiddleWare)
session
type user struct {
Id string
Name string
}
func Sessions() {
r := gin.Default()
//创建基于cookie的存储引擎,secret参数是用于加密的密钥
store := cookie.NewStore([]byte("secret"))
//路由上加入session中间件,参数mysession,指的是session的名字,也是cookie的名字
r.Use(sessions.Sessions("mysession", store))
//session 使用的编解码器是自带的gob,所以存储类似: struct、map 这些对象时需要先注册对象,不然会报错
gob.Register(user{})
}
//session 在创建时有一个配置项,可以配置session过期时间、cookie、domain、secure、path等参数
store.Options(sessions.Options{
Secure: true,
SameSite: 4,
Path: "/",
MaxAge: m.MaxAge,
})
//调用 session 方法: Set()、 Delete()、 Clear()、方法后,必须调用一次 Save() 方法。否则session数据不会更新
如果已登录。向前端返回session中存储的id和那么
//session.Get()得到的值类型为interface,无法直接返回,需要转为string
func sessionHandler(c *gin.Context) {
session := sessions.Default(c)
//session := sessions.Default(c)
Id := session.Get("Id")
Name := session.Get("Name")
if Id != nil && Name != nil {
data := gin.H{"user_id": Id.(uint), "name": Name.(string)}
c.JSON(http.StatusOK, gin.H{
"errno": "0", "errmsg": "OK", "data": data})
} else {
c.JSON(http.StatusOK, gin.H{
"errno": "4101", "errmsg": "未登录",
})
}
}
gin框架使用base64Captch+redis实现图片验证码。
//只需要普通图片验证码,可以把audio、chinese等验证码代码删掉
package captcha
import (
"fmt"
"github.com/mojocn/base64Captcha"
"iHome/Databases"
"time"
)
const CAPTCHA = "captcha:"
type RedisStore struct {
}
//// 默认存储10240个验证码,每个验证码10分钟过期
//var store = base64Captcha.DefaultMemStore
//配置RedisStore RedisStore实现base64Captcha.Store的接口
var store base64Captcha.Store = RedisStore{}
type configJsonBody struct {
Id string
CaptchaType string
VerifyValue string
DriverString *base64Captcha.DriverString
DriverAudio *base64Captcha.DriverAudio
DriverChinese *base64Captcha.DriverChinese
DriverMath *base64Captcha.DriverMath
DriverDigit *base64Captcha.DriverDigit
}
// 生成图片验证码,并且实现需求:验证码id为前端传来的uuid
func GenerateCaptcha(uuid string) (id, b64s string, err error) {
// 生成默认数字
//driver := base64Captcha.DefaultDriverDigit
// 此尺寸的调整需要根据网站进行调试,链接:
// https://captcha.mojotv.cn/
var driver base64Captcha.Driver
var param configJsonBody = configJsonBody{
Id: "string",
CaptchaType: "string",
VerifyValue: "",
DriverString: &base64Captcha.DriverString{
Length: 4,
Height: 60,
Width: 240,
ShowLineOptions: 2,
NoiseCount: 0,
Source: "1234567890qwertyuioplkjhgfdsazxcvbnm",
},
}
////ConvertFonts 按名称加载字体
switch param.CaptchaType {
case "audio":
driver = param.DriverAudio
case "string":
driver = param.DriverString.ConvertFonts()
case "math":
driver = param.DriverMath.ConvertFonts()
case "chinese":
driver = param.DriverChinese.ConvertFonts()
default:
driver = param.DriverDigit
}
c := base64Captcha.NewCaptcha(driver, store)
_, content, answer := c.Driver.GenerateIdQuestionAnswer()
id = uuid
item, err := c.Driver.DrawCaptcha(content)
if err != nil {
return "", "", err
}
err = c.Store.Set(id, answer)
if err != nil {
return "", "", err
}
b64s = item.EncodeB64string()
return
}
//如果使用轮子自己生成的id
//func generateCaptcha() (id, b64s string, err error) {
// //var driver = NewDriver().ConvertFonts()
// var driver base64Captcha.Driver
// //配置验证码的参数
// driverString := base64Captcha.DriverString{
// Height: 40,
// Width: 100,
// NoiseCount: 0,
// ShowLineOptions: 2 | 4,
// Length: 4,
// Source: "1234567890qwertyuioplkjhgfdsazxcvbnm",
// BgColor: &color.RGBA{R: 3, G: 102, B: 214, A: 125},
// Fonts: []string{"wqy-microhei.ttc"},
// }
// driver = driverString.ConvertFonts()
// c := base64Captcha.NewCaptcha(driver, store)
// return c.Generate()
//}
//实现设置captcha的方法
func (r RedisStore) Set(id string, value string) error {
key := CAPTCHA + id
//time.Minute*2:有效时间2分钟
err := Databases.RedisDb.Set(key, value, time.Minute*20).Err()
return err
}
//实现获取captcha的方法
func (r RedisStore) Get(id string, clear bool) string {
key := CAPTCHA + id
val, err := Databases.RedisDb.Get(key).Result()
if err != nil {
fmt.Println(err)
return ""
}
if clear {
//clear为true,验证通过,删除这个验证码
err := Databases.RedisDb.Del(key).Err()
if err != nil {
fmt.Println(err)
return ""
}
}
return val
}
// 校验图片验证码,并清除内存空间
//实现验证captcha的方法
func (r RedisStore) Verify(id, answer string, clear bool) bool {
v := RedisStore{}.Get(id, clear)
//fmt.Println("key:"+id+";value:"+v+";answer:"+answer)
return v == answer
}
func CapthcaVerify(id, answer string) bool {
s := store.Verify(id, answer, true)
return s
}
//返回格式:图片类型
//content_type='image/jpg'
func getCaptchaHandler(c *gin.Context) {
//获取前端传来的uuid
cur := c.Query("cur")
//pre := c.Query("pre")
_, b64s, err := captcha.GenerateCaptcha(cur)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": 2001,
"errmsg": "参数错误",
})
return
}
mypngList := strings.Split(b64s, ",")
mypng := mypngList[len(mypngList)-1]
imageBuffer, _ := base64.StdEncoding.DecodeString(mypng)
_, _ = c.Writer.WriteString(string(imageBuffer))
}