diff --git a/app/api/user/user.go b/app/api/user/user.go deleted file mode 100644 index a046dcf..0000000 --- a/app/api/user/user.go +++ /dev/null @@ -1,81 +0,0 @@ -package user - -import ( - "gfast/app/service/user" - "gfast/library/response" - "github.com/gogf/gf/net/ghttp" - "github.com/gogf/gf/util/gvalid" -) - -//用户API管理对象 -type Controller struct {} - -//用户注册接口 -func (c Controller) SignUp(r *ghttp.Request) { - if err:=user.SignUp(r.GetPostMapStrStr());err!=nil{ - response.Json(r, 1, err.Error()) - }else{ - response.Json(r, 0, "ok") - } -} - - -// 用户登录接口 -func (c *Controller) SignIn(r *ghttp.Request) { - data := r.GetPostMapStrStr() - rules := map[string]string{ - "passport": "required", - "password": "required", - } - msgs := map[string]interface{}{ - "passport": "账号不能为空", - "password": "密码不能为空", - } - if e := gvalid.CheckMap(data, rules, msgs); e != nil { - response.Json(r, 1, e.String()) - } - if err := user.SignIn(data["passport"], data["password"], r.Session); err != nil { - response.Json(r, 1, err.Error()) - } else { - response.Json(r, 0, "ok") - } -} - -// 判断用户是否已经登录 -func (c *Controller) IsSignedIn(r *ghttp.Request) { - if user.IsSignedIn(r.Session) { - response.Json(r, 0, "ok") - } else { - response.Json(r, 1, "") - } -} - -// 用户注销/退出接口 -func (c *Controller) SignOut(r *ghttp.Request) { - user.SignOut(r.Session) - response.Json(r, 0, "ok") -} - -// 检测用户账号接口(唯一性校验) -func (c *Controller) CheckPassport(r *ghttp.Request) { - passport := r.GetString("passport") - if e := gvalid.Check(passport, "required", "请输入账号"); e != nil { - response.Json(r, 1, e.String()) - } - if user.CheckPassport(passport) { - response.Json(r, 0, "ok") - } - response.Json(r, 1, "账号已经存在") -} - -// 检测用户昵称接口(唯一性校验) -func (c *Controller) CheckNickName(r *ghttp.Request) { - nickname := r.Get("nickname") - if e := gvalid.Check(nickname, "required", "请输入昵称"); e != nil { - response.Json(r, 1, e.String()) - } - if user.CheckNickName(r.GetString("nickname")) { - response.Json(r, 0, "ok") - } - response.Json(r, 1, "昵称已经存在") -} diff --git a/app/controller/admin/public.go b/app/controller/admin/public.go index c1dbf3e..e074b57 100644 --- a/app/controller/admin/public.go +++ b/app/controller/admin/public.go @@ -1,8 +1,10 @@ package admin import ( - "gfast/app/service/user" + "gfast/app/service/user_service" "gfast/library/response" + "gfast/library/utils" + "github.com/gogf/gf/frame/g" "github.com/gogf/gf/net/ghttp" "github.com/gogf/gf/util/gvalid" "github.com/mojocn/base64Captcha" @@ -13,54 +15,29 @@ type Public struct{} //Login 用户登陆验证 func (p *Public) Login(r *ghttp.Request) { data := r.GetPostMapStrStr() + //判断验证码是否正确 + if !base64Captcha.VerifyCaptchaAndIsClear(data["idKeyC"], data["idValueC"], true) { + response.JsonExit(r, response.ErrorCode, "验证失败") + } rules := map[string]string{ - "passport": "required", + "username": "required", "password": "required", } msgs := map[string]interface{}{ - "passport": "账号不能为空", + "username": "账号不能为空", "password": "密码不能为空", } if e := gvalid.CheckMap(data, rules, msgs); e != nil { - response.Json(r, 1, e.String()) + response.JsonExit(r, response.ErrorCode, e.String()) } - if err := user.SignIn(data["passport"], data["password"], r.Session); err != nil { - response.Json(r, 1, err.Error()) + if err := user_service.SignIn(data["username"], data["password"], r.Session); err != nil { + response.RJson(r, response.NotAcceptableCode, err.Error()) } else { - response.Json(r, 0, "ok") + response.SusJson(false, r, "ok") } } func (p *Public) Verify(r *ghttp.Request) { - //字符,公式,验证码配置 - var configC = base64Captcha.ConfigCharacter{ - Height: 60, - Width: 240, - //const CaptchaModeNumber:数字,CaptchaModeAlphabet:字母,CaptchaModeArithmetic:算术,CaptchaModeNumberAlphabet:数字字母混合. - Mode: base64Captcha.CaptchaModeNumberAlphabet, - ComplexOfNoiseText: base64Captcha.CaptchaComplexLower, - ComplexOfNoiseDot: base64Captcha.CaptchaComplexLower, - IsShowHollowLine: false, - IsShowNoiseDot: false, - IsShowNoiseText: false, - IsShowSlimeLine: false, - IsShowSineLine: true, - CaptchaLen: 4, - } - //创建字符公式验证码. - //GenerateCaptcha 第一个参数为空字符串,包会自动在服务器一个随机种子给你产生随机uiid. - idKeyC, capC := base64Captcha.GenerateCaptcha("8nM77YhE2xOvU6GMQ33A", configC) - //以base64编码 - base64stringC := base64Captcha.CaptchaWriteToBase64Encoding(capC) - r.Response.Header().Set("Content-type", "text/html") - r.Response.Write(idKeyC, "\n", "") -} - -func (p *Public) CheckVerify(r *ghttp.Request) { - data := r.GetQueryMapStrStr() - if base64Captcha.VerifyCaptchaAndIsClear(data["key"], data["value"], false) { - r.Response.Write("验证成功") - } else { - r.Response.Write("验证失败") - } + idKeyC, base64stringC := utils.GetVerifyImg() + response.RJson(r, 200, "ok", g.MapStrStr{"idKeyC": idKeyC, "base64stringC": base64stringC}) } diff --git a/app/model/qxkj_user/qxkj_user.go b/app/model/qxkj_user/qxkj_user.go deleted file mode 100644 index 598e71d..0000000 --- a/app/model/qxkj_user/qxkj_user.go +++ /dev/null @@ -1,3 +0,0 @@ -package qxkj_user - -// Fill with you ideas below. diff --git a/app/service/user/user.go b/app/service/user/user.go deleted file mode 100644 index 3127f89..0000000 --- a/app/service/user/user.go +++ /dev/null @@ -1,91 +0,0 @@ -package user - -import ( - "database/sql" - "errors" - "fmt" - "github.com/gogf/gf/frame/g" - "github.com/gogf/gf/net/ghttp" - "github.com/gogf/gf/os/gtime" - "github.com/gogf/gf/util/gvalid" -) - -const USER_SESSION_MARK = "user_info" - -var ( - //表对象 - table = g.DB().Table("user").Safe() -) - -//用户注册 -func SignUp(data g.MapStrStr)error{ - //数据校验 - rules:=[]string{ - "passport @required|length:6,16#账号不能为空|账号长度应在:min到:max之间", - "password2@required|length:6,16#请输入确认密码|密码长度应当在:min到:max之间", - "password @required|length:6,16|same:password2#密码不能为空|密码长度应当在:min到:max之间|两次密码输入不相等", - } - if err:=gvalid.CheckMap(data,rules);err!=nil{ - return errors.New(err.String()) - } - if _, ok := data["nickname"]; !ok { - data["nickname"] = data["passport"] - } - // 唯一性数据检查 - if !CheckPassport(data["passport"]) { - return errors.New(fmt.Sprintf("账号 %s 已经存在", data["passport"])) - } - if !CheckNickName(data["nickname"]) { - return errors.New(fmt.Sprintf("昵称 %s 已经存在", data["nickname"])) - } - // 记录账号创建/注册时间 - if _, ok := data["create_time"]; !ok { - data["create_time"] = gtime.Now().String() - } - if _, err := table.Filter().Data(data).Save(); err != nil { - return err - } - return nil -} - -// 判断用户是否已经登录 -func IsSignedIn(session *ghttp.Session) bool { - return session.Contains(USER_SESSION_MARK) -} - -// 用户登录,成功返回用户信息,否则返回nil; passport应当会md5值字符串 -func SignIn(passport, password string, session *ghttp.Session) error { - record, err := table.Where("passport=? and password=?", passport, password).One() - if err != nil && err != sql.ErrNoRows { - return err - } - if record == nil { - return errors.New("账号或密码错误") - } - session.Set(USER_SESSION_MARK, record) - return nil -} - -// 用户注销 -func SignOut(session *ghttp.Session) { - session.Remove(USER_SESSION_MARK) -} - - -// 检查账号是否符合规范(目前仅检查唯一性),存在返回false,否则true -func CheckPassport(passport string) bool { - if i, err := table.Where("passport", passport).Count(); err != nil && err != sql.ErrNoRows { - return false - } else { - return i == 0 - } -} - -// 检查昵称是否符合规范(目前仅检查唯一性),存在返回false,否则true -func CheckNickName(nickname string) bool { - if i, err := table.Where("nickname", nickname).Count(); err != nil && err != sql.ErrNoRows { - return false - } else { - return i == 0 - } -} \ No newline at end of file diff --git a/app/service/user_service/qxkj_user.go b/app/service/user_service/qxkj_user.go new file mode 100644 index 0000000..5c8cad0 --- /dev/null +++ b/app/service/user_service/qxkj_user.go @@ -0,0 +1,21 @@ +package user_service + +import ( + "database/sql" + "errors" + "gfast/app/model/qxkj_user" + "github.com/gogf/gf/net/ghttp" +) + +// 用户登录,成功返回用户信息,否则返回nil; passport应当会md5值字符串 +func SignIn(username, password string, session *ghttp.Session) error { + qxkjUser, err := qxkj_user.Model.Where("username=? and user_password=?", username, password).One() + if err != nil && err != sql.ErrNoRows { + return err + } + if qxkjUser == nil { + return errors.New("账号或密码错误") + } + //session.Set(USER_SESSION_MARK, record) + return nil +} diff --git a/boot/boot.go b/boot/boot.go index 33ce726..0765cda 100644 --- a/boot/boot.go +++ b/boot/boot.go @@ -1,8 +1,19 @@ package boot -import "github.com/gogf/gf/frame/g" +import ( + "github.com/goflyfox/gtoken/gtoken" + "github.com/gogf/gf/frame/g" +) func init() { g.Server().SetPort(8200) g.Server().AddStaticPath("/public", g.Cfg().Get("server.ServerRoot").(string)) + // 启动gtoken + gtoken := >oken.GfToken{ + LoginPath: "/login", + LoginBeforeFunc: loginFunc, + LogoutPath: "/user/logout", + AuthPaths: g.SliceStr{"/system/*"}, + } + gtoken.Start() } diff --git a/go.mod b/go.mod index 8e1bae1..3ada2d4 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,9 @@ module gfast require ( github.com/casbin/casbin/v2 v2.1.2 + github.com/goflyfox/gtoken v1.3.9 // indirect github.com/gogf/gf v1.10.1 github.com/mojocn/base64Captcha v1.2.2 - google.golang.org/appengine v1.6.5 // indirect ) go 1.13 diff --git a/library/response/response.go b/library/response/response.go index 830d984..a5da8b2 100644 --- a/library/response/response.go +++ b/library/response/response.go @@ -5,25 +5,41 @@ import ( "github.com/gogf/gf/net/ghttp" ) +const ( + SuccessCode int = 200 + ErrorCode int = 400 + AccessDeniedCode int = 403 + NotFoundCode int = 404 + NotAcceptableCode int = 406 + ServerErrorCode int = 500 + RedirectCode int = 302 +) + +// 返回JSON数据并退出当前HTTP执行函数。 +func JsonExit(r *ghttp.Request, code int, msg string, data ...interface{}) { + RJson(r, code, msg, data...) + r.Exit() +} + // 标准返回结果数据结构封装。 // 返回固定数据结构的JSON: -// err: 错误码(0:成功, 1:失败, >1:错误码); +// code: 状态码(200:成功,302跳转,和http请求状态码一至); // msg: 请求结果信息; // data: 请求结果,根据不同接口返回结果的数据结构不同; -func Json(r *ghttp.Request, err int, msg string, data ...interface{}) { +func RJson(r *ghttp.Request, code int, msg string, data ...interface{}) { responseData := interface{}(nil) - if len(data) > 0 { - responseData = data[0] - } + responseData = data r.Response.WriteJson(g.Map{ - "err": err, + "code": code, "msg": msg, "data": responseData, }) } -// 返回JSON数据并退出当前HTTP执行函数。 -func JsonExit(r *ghttp.Request, err int, msg string, data ...interface{}) { - Json(r, err, msg, data...) - r.Exit() +//成功返回JSON +func SusJson(isExit bool, r *ghttp.Request, msg string, data ...interface{}) { + if isExit { + JsonExit(r, SuccessCode, msg, data...) + } + RJson(r, SuccessCode, msg, data...) } diff --git a/library/utils/function.go b/library/utils/function.go new file mode 100644 index 0000000..e1e2136 --- /dev/null +++ b/library/utils/function.go @@ -0,0 +1,29 @@ +package utils + +import "github.com/mojocn/base64Captcha" + +//获取验证码 +func GetVerifyImg() (idKeyC string, base64stringC string) { + //字符,公式,验证码配置 + var configC = base64Captcha.ConfigCharacter{ + Height: 60, + Width: 240, + //const CaptchaModeNumber:数字,CaptchaModeAlphabet:字母,CaptchaModeArithmetic:算术,CaptchaModeNumberAlphabet:数字字母混合. + Mode: base64Captcha.CaptchaModeNumberAlphabet, + ComplexOfNoiseText: base64Captcha.CaptchaComplexLower, + ComplexOfNoiseDot: base64Captcha.CaptchaComplexLower, + IsShowHollowLine: false, + IsShowNoiseDot: false, + IsShowNoiseText: false, + IsShowSlimeLine: false, + IsShowSineLine: true, + CaptchaLen: 4, + } + //创建字符公式验证码. + //GenerateCaptcha 第一个参数为空字符串,包会自动在服务器一个随机种子给你产生随机uiid. + var capC base64Captcha.CaptchaInterface + idKeyC, capC = base64Captcha.GenerateCaptcha("8nM77YhE2xOvU6GMQ33A", configC) + //以base64编码 + base64stringC = base64Captcha.CaptchaWriteToBase64Encoding(capC) + return idKeyC, base64stringC +} diff --git a/router/middleware.go b/router/middleware.go new file mode 100644 index 0000000..dc451fb --- /dev/null +++ b/router/middleware.go @@ -0,0 +1,8 @@ +package router + +import "github.com/gogf/gf/net/ghttp" + +func MiddlewareCORS(r *ghttp.Request) { + r.Response.CORSDefault() + r.Middleware.Next() +} diff --git a/router/router.go b/router/router.go index 5daa027..a075bae 100644 --- a/router/router.go +++ b/router/router.go @@ -1,7 +1,6 @@ package router import ( - "gfast/app/api/user" "gfast/app/controller/admin" "github.com/gogf/gf/frame/g" ) @@ -9,6 +8,8 @@ import ( // 统一路由注册. func init() { s := g.Server() - s.BindObject("/user", new(user.Controller)) - s.BindObject("/system/public", new(admin.Public)) + group := s.Group("/") + group.Middleware(MiddlewareCORS) + systemGroup := group.Group("/system") + systemGroup.ALL("/public", new(admin.Public)) }