service.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. package service
  2. import (
  3. "database/sql"
  4. "errors"
  5. "gfast/app/model/admin/sys_login_log"
  6. "gfast/app/model/admin/user"
  7. "gfast/app/model/admin/user_online"
  8. "gfast/library/response"
  9. "gfast/library/utils"
  10. "github.com/goflyfox/gtoken/gtoken"
  11. "github.com/gogf/gf/crypto/gmd5"
  12. "github.com/gogf/gf/frame/g"
  13. "github.com/gogf/gf/net/ghttp"
  14. "github.com/gogf/gf/os/gtime"
  15. "github.com/gogf/gf/util/gconv"
  16. "github.com/gogf/gf/util/gvalid"
  17. "github.com/mojocn/base64Captcha"
  18. "github.com/mssola/user_agent"
  19. "strings"
  20. )
  21. //版本号
  22. const Version = "1.0.01"
  23. var (
  24. AdminMultiLogin bool //是否允许后台管理员多端登陆
  25. AdminPageNum = 20 //后台分页长度
  26. NotCheckAuthAdminIds []int //无需验证权限的用户id
  27. )
  28. //获取数字验证码
  29. func GetVerifyImgDigit() (idKeyC string, base64stringC string) {
  30. driver := &base64Captcha.DriverDigit{80, 240, 5, 0.7, 5}
  31. store := base64Captcha.DefaultMemStore
  32. c := base64Captcha.NewCaptcha(driver, store)
  33. idKeyC, base64stringC, err := c.Generate()
  34. if err != nil {
  35. g.Log().Error(err)
  36. }
  37. return
  38. }
  39. //获取字母数字混合验证码
  40. func GetVerifyImgString() (idKeyC string, base64stringC string) {
  41. driver := &base64Captcha.DriverString{
  42. Height: 80,
  43. Width: 240,
  44. NoiseCount: 50,
  45. ShowLineOptions: 20,
  46. Length: 4,
  47. Source: "abcdefghijklmnopqrstuvwxyz0123456789",
  48. Fonts: []string{"chromohv.ttf"},
  49. }
  50. driver = driver.ConvertFonts()
  51. store := base64Captcha.DefaultMemStore
  52. c := base64Captcha.NewCaptcha(driver, store)
  53. idKeyC, base64stringC, err := c.Generate()
  54. if err != nil {
  55. g.Log().Error(err)
  56. }
  57. return
  58. }
  59. //验证输入的验证码是否正确
  60. func VerifyString(id, answer string) bool {
  61. driver := new(base64Captcha.DriverString)
  62. store := base64Captcha.DefaultMemStore
  63. c := base64Captcha.NewCaptcha(driver, store)
  64. return c.Verify(id, answer, true)
  65. }
  66. func FrontLogin(r *ghttp.Request) (string, interface{}) {
  67. g.Log().Println("front login test...")
  68. return "test", nil
  69. }
  70. //AdminLogin 后台用户登陆验证
  71. func AdminLogin(r *ghttp.Request) (string, interface{}) {
  72. data := r.GetFormMapStrStr()
  73. rules := map[string]string{
  74. "idValueC": "required",
  75. "username": "required",
  76. "password": "required",
  77. }
  78. msgs := map[string]interface{}{
  79. "idValueC": "请输入验证码",
  80. "username": "账号不能为空",
  81. "password": "密码不能为空",
  82. }
  83. if e := gvalid.CheckMap(data, rules, msgs); e != nil {
  84. response.JsonExit(r, response.ErrorCode, e.String())
  85. }
  86. //判断验证码是否正确
  87. if !VerifyString(data["idKeyC"], data["idValueC"]) {
  88. response.JsonExit(r, response.ErrorCode, "验证码输入错误")
  89. }
  90. password := utils.EncryptCBC(data["password"], utils.AdminCbcPublicKey)
  91. var keys string
  92. if AdminMultiLogin {
  93. keys = data["username"] + password + gmd5.MustEncryptString(r.GetClientIp())
  94. } else {
  95. keys = data["username"] + password
  96. }
  97. ip := r.GetClientIp()
  98. userAgent := r.Header.Get("User-Agent")
  99. if err, user := signIn(data["username"], password, r); err != nil {
  100. go loginLog(0, data["username"], ip, userAgent, err.Error())
  101. response.JsonExit(r, response.ErrorCode, err.Error())
  102. } else {
  103. //判断是否后台用户
  104. if user.IsAdmin != 1 {
  105. response.JsonExit(r, response.ErrorCode, "抱歉!此用户不属于后台管理员!")
  106. }
  107. r.SetParam("userInfo", user)
  108. go loginLog(1, data["username"], ip, userAgent, "登录成功")
  109. return keys, user
  110. }
  111. return keys, nil
  112. }
  113. // 后台登录返回方法
  114. func AdminLoginAfter(r *ghttp.Request, respData gtoken.Resp) {
  115. if !respData.Success() {
  116. r.Response.WriteJson(respData)
  117. } else {
  118. token := respData.GetString("token")
  119. uuid := respData.GetString("uuid")
  120. var userInfo *user.Entity
  121. r.GetParamVar("userInfo").Struct(&userInfo)
  122. //保存用户在线状态token到数据库
  123. userAgent := r.Header.Get("User-Agent")
  124. ua := user_agent.New(userAgent)
  125. os := ua.OS()
  126. explorer, _ := ua.Browser()
  127. entity := user_online.Entity{
  128. Uuid: uuid,
  129. Token: token,
  130. CreateTime: gconv.Uint64(gtime.Timestamp()),
  131. UserName: userInfo.UserName,
  132. Ip: r.GetClientIp(),
  133. Explorer: explorer,
  134. Os: os,
  135. }
  136. entity.Save()
  137. r.Response.WriteJson(gtoken.Succ(g.Map{
  138. "token": token,
  139. }))
  140. }
  141. }
  142. //gtoken验证后返回
  143. func AuthAfterFunc(r *ghttp.Request, respData gtoken.Resp) {
  144. if r.Method == "OPTIONS" || respData.Success() {
  145. r.Middleware.Next()
  146. } else {
  147. respData.Msg = "用户信息验证失败"
  148. response := r.Response
  149. options := response.DefaultCORSOptions()
  150. response.CORS(options)
  151. response.WriteJson(respData)
  152. r.ExitAll()
  153. }
  154. }
  155. //后台退出登陆
  156. func AdminLoginOut(r *ghttp.Request) bool {
  157. //删除在线用户状态
  158. authHeader := r.Header.Get("Authorization")
  159. if authHeader != "" {
  160. parts := strings.SplitN(authHeader, " ", 2)
  161. if len(parts) == 2 && parts[0] == "Bearer" && parts[1] != "" {
  162. //删除在线用户状态操作
  163. user_online.Model.Delete("token", parts[1])
  164. }
  165. }
  166. authHeader = r.GetString("token")
  167. if authHeader != "" {
  168. //删除在线用户状态操作
  169. user_online.Model.Delete("token", authHeader)
  170. }
  171. return true
  172. }
  173. // 用户登录,成功返回用户信息,否则返回nil
  174. func signIn(username, password string, r *ghttp.Request) (error, *user.User) {
  175. user, err := user.Model.Where("user_name=? and user_password=?", username, password).One()
  176. if err != nil && err != sql.ErrNoRows {
  177. return err, nil
  178. }
  179. if user == nil {
  180. return errors.New("账号或密码错误"), nil
  181. }
  182. //判断用户状态
  183. if user.UserStatus == 0 {
  184. return errors.New("用户已被冻结"), nil
  185. }
  186. returnData := *user
  187. //更新登陆时间及ip
  188. user.LastLoginTime = gconv.Int(gtime.Timestamp())
  189. user.LastLoginIp = r.GetClientIp()
  190. user.Update()
  191. return nil, &returnData
  192. }
  193. //登录日志记录
  194. func loginLog(status int, username, ip, userAgent, msg string) {
  195. var log sys_login_log.Entity
  196. log.LoginName = username
  197. log.Ipaddr = ip
  198. log.LoginLocation = utils.GetCityByIp(log.Ipaddr)
  199. ua := user_agent.New(userAgent)
  200. log.Browser, _ = ua.Browser()
  201. log.Os = ua.OS()
  202. log.Status = status
  203. log.Msg = msg
  204. log.LoginTime = gtime.Timestamp()
  205. log.Save()
  206. }