package middle
import (
jwt "github.com/gogf/gf-jwt"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
"github.com/gogf/gf/os/glog"
"github.com/gogf/gf/util/gvalid"
"time"
)
var (
// 底层JWT中间件。
GfJWTMiddleware *jwt.GfJWTMiddleware
// 自定义登录参数验证规则。
ValidationRules = g.Map{
"username": "required",
"password": "required",
}
)
// 初始化函数,
// 重写此函数以自定义您自己的JWT设置.
func init() {
authMiddleware, err := jwt.New(&jwt.GfJWTMiddleware{
Realm: "test zone",
Key: []byte("secret key"),
Timeout: time.Minute * 5,
MaxRefresh: time.Minute * 5,
IdentityKey: "id",
TokenLookup: "header: Authorization, query: token, cookie: jwt",
TokenHeadName: "Bearer",
TimeFunc: time.Now,
//Authenticator: (&api.MemberController{}).Authenticator, //这里我在router中覆写
LoginResponse: LoginResponse,
RefreshResponse: RefreshResponse,
Unauthorized: Unauthorized,
IdentityHandler: IdentityHandler,
PayloadFunc: PayloadFunc,
CookieHTTPOnly: true,
})
if err != nil {
glog.Fatal("JWT Error:" + err.Error())
}
GfJWTMiddleware = authMiddleware
}
//PayloadFunc是在登录期间调用的回调函数。
//使用此函数可以向webtoken添加其他负载数据。
//然后通过c.Get(“JWT_PAYLOAD”)在请求期间提供数据。
//请注意,有效负载未加密。
//jwt.io中提到的属性不能用作映射的键。
//可选,默认情况下不设置其他数据。
func PayloadFunc(data interface{}) jwt.MapClaims {
claims := jwt.MapClaims{}
params := data.(map[string]interface{})
if len(params) > 0 {
for k, v := range params {
claims[k] = v
}
}
return claims
}
// IdentityHandler设置JWT的标识。
func IdentityHandler(r *ghttp.Request) interface{} {
claims := jwt.ExtractClaims(r)
return claims["id"]
}
// Unauthorized用于定义自定义的Unauthorized回调函数。
func Unauthorized(r *ghttp.Request, code int, message string) {
r.Response.WriteJson(g.Map{
"isSuccess": false,
"errMsg": message,
})
}
// LoginResponse用于定义自定义的登录成功回调函数。
func LoginResponse(r *ghttp.Request, code int, token string, expire time.Time) {
r.Response.WriteJson(g.Map{
"isSuccess": true,
"data": g.Map{
"token": token,
"expire": expire.Format(time.RFC3339),
},
})
}
// RefreshResponse用于获取新令牌,无论当前令牌是否过期.
func RefreshResponse(r *ghttp.Request, code int, token string, expire time.Time) {
r.Response.WriteJson(g.Map{
"isSuccess": true,
"data": g.Map{
"token": token,
"expire": expire.Format(time.RFC3339),
},
})
}
//身份验证器用于验证登录参数。
//它必须返回用户数据作为用户标识符,它将存储在声明数组中。
//检查错误(e)以确定适当的错误消息。
func Authenticator(r *ghttp.Request) (interface{}, error) {
data := r.GetMap()
if e := gvalid.CheckMap(data, ValidationRules); e != nil {
return "", jwt.ErrFailedAuthentication
}
if data["username"] == "admin" && data["password"] == "admin" {
return g.Map{
"username": data["username"],
"id": data["username"], //require!!!
"role": "user",
}, nil
}
return nil, jwt.ErrFailedAuthentication
}