package handler import ( "git.ilapage.cn/ila/yovision/Sense/server/app/admin/models" "git.ilapage.cn/ila/yovision/Sense/server/common" "net/http" "github.com/gin-gonic/gin" "github.com/go-admin-team/go-admin-core/sdk/api" "github.com/go-admin-team/go-admin-core/sdk/pkg" jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth" "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user" "github.com/go-admin-team/go-admin-core/sdk/pkg/response" "github.com/mssola/user_agent" ) func PayloadFunc(data interface{}) jwt.MapClaims { if v, ok := data.(map[string]interface{}); ok { u, _ := v["user"].(SysUser) r, _ := v["role"].(SysRole) return jwt.MapClaims{ jwt.IdentityKey: u.UserId, jwt.RoleIdKey: r.RoleId, jwt.RoleKey: r.RoleKey, jwt.NiceKey: u.Username, jwt.DataScopeKey: r.DataScope, jwt.RoleNameKey: r.RoleKey, } } return jwt.MapClaims{} } func IdentityHandler(c *gin.Context) interface{} { claims := jwt.ExtractClaims(c) return map[string]interface{}{ "IdentityKey": claims["identity"], "UserName": claims["nice"], "RoleKey": claims["rolekey"], "UserId": claims["identity"], "RoleIds": claims["roleid"], "DataScope": claims["datascope"], } } // Authenticator 获取token // @Summary 登陆 // @Description 获取token // @Description LoginHandler can be used by clients to get a jwt token. // @Description Payload needs to be json in the form of {"username": "USERNAME", "password": "PASSWORD"}. // @Description Reply will be of the form {"token": "TOKEN"}. // @Description dev mode:It should be noted that all fields cannot be empty, and a value of 0 can be passed in addition to the account password // @Description 注意:开发模式:需要注意全部字段不能为空,账号密码外可以传入0值 // @Tags 登陆 // @Accept application/json // @Product application/json // @Param account body Login true "account" // @Success 200 {string} string "{"code": 200, "expire": "2019-08-07T12:45:48+08:00", "token": ".eyJleHAiOjE1NjUxNTMxNDgsImlkIjoiYWRtaW4iLCJvcmlnX2lhdCI6MTU2NTE0OTU0OH0.-zvzHvbg0A" }" // @Router /api/v1/login [post] func Authenticator(c *gin.Context) (interface{}, error) { log := api.GetRequestLogger(c) db, err := pkg.GetOrm(c) if err != nil { log.Errorf("get db error, %s", err.Error()) response.Error(c, 500, err, "数据库连接获取失败") return nil, jwt.ErrFailedAuthentication } var loginVals Login var status = "2" var msg = "登录成功" var username = "" defer func() { LoginLogToDB(c, status, msg, username) }() if err = c.ShouldBind(&loginVals); err != nil { username = loginVals.Username msg = "数据解析失败" status = "1" return nil, jwt.ErrMissingLoginValues } sysUser, role, e := loginVals.GetUser(db) if e == nil { username = loginVals.Username return map[string]interface{}{"user": sysUser, "role": role}, nil } else { username = loginVals.Username msg = "登录失败" status = "1" log.Warnf("%s login failed!", loginVals.Username) } return nil, jwt.ErrFailedAuthentication } // LoginLogToDB Write log to database func LoginLogToDB(c *gin.Context, status string, msg string, username string) { WriteIdentityAudit(c, status, msg, username) } // WriteIdentityAudit persists identity/security events synchronously. It never // records request bodies, credentials, tokens, captcha answers, or cookies. func WriteIdentityAudit(c *gin.Context, status string, msg string, username string) { log := api.GetRequestLogger(c) db, err := pkg.GetOrm(c) if err != nil { log.Errorf("identity audit database unavailable: %s", err.Error()) return } ua := user_agent.New(c.Request.UserAgent()) browserName, browserVersion := ua.Browser() l := models.SysLoginLog{ Username: truncateAuditText(username, 128), Status: status, Ipaddr: truncateAuditText(common.GetClientIP(c), 255), LoginLocation: "", Browser: truncateAuditText(browserName+" "+browserVersion, 255), Os: truncateAuditText(ua.OS(), 255), Platform: truncateAuditText(ua.Platform(), 255), LoginTime: pkg.GetCurrentTime(), Remark: truncateAuditText(c.Request.Method+" "+c.FullPath(), 255), Msg: truncateAuditText(msg, 255), } if err = db.Create(&l).Error; err != nil { log.Errorf("identity audit write failed: %s", err.Error()) } } func truncateAuditText(value string, limit int) string { runes := []rune(value) if len(runes) <= limit { return value } return string(runes[:limit]) } // LogOut // @Summary 退出登录 // @Description 获取token // LoginHandler can be used by clients to get a jwt token. // Reply will be of the form {"token": "TOKEN"}. // @Accept application/json // @Product application/json // @Success 200 {string} string "{"code": 200, "msg": "成功退出系统" }" // @Router /logout [post] // @Security Bearer func LogOut(c *gin.Context) { LoginLogToDB(c, "2", "退出成功", user.GetUserName(c)) c.JSON(http.StatusOK, gin.H{ "code": 200, "msg": "退出成功", }) } func Authorizator(data interface{}, c *gin.Context) bool { if v, ok := data.(map[string]interface{}); ok { u, _ := v["user"].(models.SysUser) r, _ := v["role"].(models.SysRole) c.Set("role", r.RoleKey) c.Set("roleIds", r.RoleId) c.Set("userId", u.UserId) c.Set("userName", u.Username) c.Set("dataScope", r.DataScope) return true } return false } func Unauthorized(c *gin.Context, code int, message string) { if c.FullPath() != "/api/v1/login" { WriteIdentityAudit(c, "1", "未认证访问被拒绝", "") } c.JSON(http.StatusOK, gin.H{ "code": code, "msg": message, }) }