ferry/handler/auth.go

223 lines
6.1 KiB
Go
Raw Normal View History

2020-07-13 20:33:20 +08:00
package handler
import (
2020-08-17 22:38:41 +08:00
"errors"
2020-08-17 01:24:51 +08:00
"ferry/global/orm"
2020-07-14 14:07:44 +08:00
"ferry/models/system"
2020-07-13 20:33:20 +08:00
jwt "ferry/pkg/jwtauth"
ldap1 "ferry/pkg/ldap"
2020-08-15 23:34:37 +08:00
"ferry/pkg/logger"
"ferry/pkg/settings"
2020-07-13 20:33:20 +08:00
"ferry/tools"
2020-08-17 01:24:51 +08:00
"fmt"
2020-07-13 20:33:20 +08:00
"net/http"
2020-08-18 00:53:02 +08:00
"time"
2020-07-13 20:33:20 +08:00
"github.com/go-ldap/ldap/v3"
2020-07-13 20:33:20 +08:00
"github.com/gin-gonic/gin"
"github.com/mojocn/base64Captcha"
"github.com/mssola/user_agent"
)
var store = base64Captcha.DefaultMemStore
func PayloadFunc(data interface{}) jwt.MapClaims {
if v, ok := data.(map[string]interface{}); ok {
2020-07-14 14:07:44 +08:00
u, _ := v["user"].(system.SysUser)
r, _ := v["role"].(system.SysRole)
2020-07-13 20:33:20 +08:00
return jwt.MapClaims{
2020-07-15 11:30:31 +08:00
jwt.IdentityKey: u.UserId,
jwt.RoleIdKey: r.RoleId,
jwt.RoleKey: r.RoleKey,
jwt.NiceKey: u.Username,
jwt.RoleNameKey: r.RoleName,
2020-07-13 20:33:20 +08:00
}
}
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"],
}
}
// @Summary 登陆
// @Description 获取token
// LoginHandler can be used by clients to get a jwt token.
// Payload needs to be json in the form of {"username": "USERNAME", "password": "PASSWORD"}.
// Reply will be of the form {"token": "TOKEN"}.
// @Accept application/json
// @Product application/json
// @Param username body models.Login true "Add account"
// @Success 200 {string} string "{"code": 200, "expire": "2019-08-07T12:45:48+08:00", "token": ".eyJleHAiOjE1NjUxNTMxNDgsImlkIjoiYWRtaW4iLCJvcmlnX2lhdCI6MTU2NTE0OTU0OH0.-zvzHvbg0A" }"
// @Router /login [post]
func Authenticator(c *gin.Context) (interface{}, error) {
2020-08-17 01:24:51 +08:00
var (
err error
loginVal system.Login
loginLog system.LoginLog
roleValue system.SysRole
authUserCount int
2020-08-18 00:53:02 +08:00
addUserInfo system.SysUser
ldapUserInfo *ldap.Entry
isVerifyCode interface{}
2020-08-17 01:24:51 +08:00
)
2020-07-13 20:33:20 +08:00
ua := user_agent.New(c.Request.UserAgent())
2020-08-17 01:24:51 +08:00
loginLog.Ipaddr = c.ClientIP()
2020-07-13 20:33:20 +08:00
location := tools.GetLocation(c.ClientIP())
2020-08-17 01:24:51 +08:00
loginLog.LoginLocation = location
loginLog.LoginTime = tools.GetCurrntTime()
loginLog.Status = "0"
loginLog.Remark = c.Request.UserAgent()
2020-07-13 20:33:20 +08:00
browserName, browserVersion := ua.Browser()
2020-08-17 01:24:51 +08:00
loginLog.Browser = browserName + " " + browserVersion
loginLog.Os = ua.OS()
loginLog.Msg = "登录成功"
loginLog.Platform = ua.Platform()
2020-07-13 20:33:20 +08:00
2020-08-17 01:24:51 +08:00
// 获取前端过来的数据
if err := c.ShouldBind(&loginVal); err != nil {
loginLog.Status = "1"
loginLog.Msg = "数据解析失败"
loginLog.Username = loginVal.Username
_, _ = loginLog.Create()
2020-07-13 20:33:20 +08:00
return nil, jwt.ErrMissingLoginValues
}
2020-08-17 01:24:51 +08:00
loginLog.Username = loginVal.Username
// 查询设置 is_verify_code
isVerifyCode, err = settings.GetContentByKey(1, "is_verify_code")
if err != nil {
return nil, errors.New("获取是否需要验证码校验失败")
}
if isVerifyCode != nil && isVerifyCode.(bool) {
// 校验验证码
if !store.Verify(loginVal.UUID, loginVal.Code, true) {
loginLog.Status = "1"
loginLog.Msg = "验证码错误"
_, _ = loginLog.Create()
return nil, jwt.ErrInvalidVerificationode
}
2020-07-13 20:33:20 +08:00
}
2020-08-17 01:24:51 +08:00
// ldap 验证
2020-08-18 00:53:02 +08:00
if loginVal.LoginType == 1 {
2020-08-17 01:24:51 +08:00
// ldap登陆
ldapUserInfo, err = ldap1.LdapLogin(loginVal.Username, loginVal.Password)
2020-08-17 01:24:51 +08:00
if err != nil {
2020-08-18 00:53:02 +08:00
return nil, err
2020-08-17 01:24:51 +08:00
}
// 2. 将ldap用户信息写入到用户数据表中
2020-08-20 13:57:05 +08:00
err = orm.Eloquent.Model(&system.SysUser{}).
2020-08-18 00:53:02 +08:00
Where("username = ?", loginVal.Username).
2020-08-17 01:24:51 +08:00
Count(&authUserCount).Error
if err != nil {
2020-08-18 00:53:02 +08:00
return nil, errors.New(fmt.Sprintf("查询用户失败,%v", err))
2020-08-17 01:24:51 +08:00
}
2020-08-19 13:36:27 +08:00
addUserInfo, err = ldap1.LdapFieldsMap(ldapUserInfo)
if err != nil {
return nil, fmt.Errorf("ldap映射本地字段失败%v", err.Error())
}
2020-08-17 01:24:51 +08:00
if authUserCount == 0 {
2020-08-18 00:53:02 +08:00
addUserInfo.Username = loginVal.Username
2020-08-17 01:24:51 +08:00
// 获取默认权限ID
2020-08-20 13:57:05 +08:00
err = orm.Eloquent.Model(&system.SysRole{}).Where("role_key = 'common'").Find(&roleValue).Error
2020-08-17 01:24:51 +08:00
if err != nil {
2020-08-18 00:53:02 +08:00
return nil, errors.New(fmt.Sprintf("查询角色失败,%v", err))
2020-08-17 01:24:51 +08:00
}
addUserInfo.RoleId = roleValue.RoleId // 绑定通用角色
2020-08-18 00:53:02 +08:00
addUserInfo.Status = "0"
addUserInfo.CreatedAt = time.Now()
addUserInfo.UpdatedAt = time.Now()
2020-08-19 13:36:27 +08:00
if addUserInfo.Sex == "" {
addUserInfo.Sex = "0"
}
2020-08-20 13:57:05 +08:00
err = orm.Eloquent.Create(&addUserInfo).Error
2020-08-17 01:24:51 +08:00
if err != nil {
2020-08-18 00:53:02 +08:00
return nil, errors.New(fmt.Sprintf("创建本地用户失败,%v", err))
2020-08-17 01:24:51 +08:00
}
}
}
user, role, e := loginVal.GetUser()
2020-07-13 20:33:20 +08:00
if e == nil {
2020-08-17 01:24:51 +08:00
_, _ = loginLog.Create()
if user.Status == "1" {
return nil, errors.New("用户已被禁用。")
}
2020-07-13 20:33:20 +08:00
return map[string]interface{}{"user": user, "role": role}, nil
} else {
2020-08-17 01:24:51 +08:00
loginLog.Status = "1"
loginLog.Msg = "登录失败"
_, _ = loginLog.Create()
2020-08-15 23:34:37 +08:00
logger.Info(e.Error())
2020-07-13 20:33:20 +08:00
}
return nil, jwt.ErrFailedAuthentication
}
// @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
func LogOut(c *gin.Context) {
2020-07-14 14:07:44 +08:00
var loginlog system.LoginLog
2020-07-13 20:33:20 +08:00
ua := user_agent.New(c.Request.UserAgent())
loginlog.Ipaddr = c.ClientIP()
location := tools.GetLocation(c.ClientIP())
loginlog.LoginLocation = location
loginlog.LoginTime = tools.GetCurrntTime()
loginlog.Status = "0"
loginlog.Remark = c.Request.UserAgent()
browserName, browserVersion := ua.Browser()
loginlog.Browser = browserName + " " + browserVersion
loginlog.Os = ua.OS()
loginlog.Platform = ua.Platform()
loginlog.Username = tools.GetUserName(c)
loginlog.Msg = "退出成功"
2020-07-17 01:20:25 +08:00
_, _ = loginlog.Create()
2020-07-13 20:33:20 +08:00
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 {
2020-07-14 14:07:44 +08:00
u, _ := v["user"].(system.SysUser)
r, _ := v["role"].(system.SysRole)
2020-07-13 20:33:20 +08:00
c.Set("role", r.RoleName)
c.Set("roleIds", r.RoleId)
c.Set("userId", u.UserId)
c.Set("userName", u.UserName)
return true
}
return false
}
func Unauthorized(c *gin.Context, code int, message string) {
c.JSON(http.StatusOK, gin.H{
"code": code,
"msg": message,
})
}