diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..29f81d812f3e768fa89638d1f72920dbfd1413a8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/api/v1/system/sys_captcha.go b/api/v1/system/sys_captcha.go new file mode 100644 index 0000000000000000000000000000000000000000..0a9bbdca4b519e021355b641d0790616fb5d42b3 --- /dev/null +++ b/api/v1/system/sys_captcha.go @@ -0,0 +1,28 @@ +package system + +import ( + "github.com/gin-gonic/gin" + "github.com/mojocn/base64Captcha" + "github/shansec/go-vue-admin/global" + "github/shansec/go-vue-admin/model/common/response" + systemRes "github/shansec/go-vue-admin/model/system/response" + "go.uber.org/zap" +) + +var store = base64Captcha.DefaultMemStore + +func (b *BaseApi) Captcha(c *gin.Context) { + // 生成默认数字 + driver := base64Captcha.NewDriverDigit(global.MAY_CONFIG.Captcha.ImgHeight, global.MAY_CONFIG.Captcha.ImgWidth, global.MAY_CONFIG.Captcha.KeyLong, 0.7, 80) + cp := base64Captcha.NewCaptcha(driver, store) + if id, b64s, err := cp.Generate(); err != nil { + global.MAY_LOGGER.Error("验证码获取失败", zap.Error(err)) + response.FailWithMessage("验证码获取失败", c) + } else { + response.OkWithDetailed(systemRes.SysCaptchaResponse{ + CaptchaId: id, + PicPath: b64s, + CaptchaLength: global.MAY_CONFIG.Captcha.KeyLong, + }, "验证码获取成功", c) + } +} diff --git a/api/v1/system/sys_user.go b/api/v1/system/sys_user.go index d409ee4889d3787f95525ece59750e0a728df45f..520d3a0106be52760d618a1a113655fe133769ad 100644 --- a/api/v1/system/sys_user.go +++ b/api/v1/system/sys_user.go @@ -28,13 +28,16 @@ func (b *BaseApi) Login(c *gin.Context) { response.FailWithMessage(err.Error(), c) return } - - u := &system.SysUser{Username: login.Username, Password: login.Password} - if user, err := userService.Login(u); err != nil { - global.MAY_LOGGER.Error("登陆失败,用户名不存在或者密码错误", zap.Error(err)) - response.FailWithMessage("用户名不存在或者密码错误", c) + if store.Verify(login.CaptchaId, login.Captcha, true) { + u := &system.SysUser{Username: login.Username, Password: login.Password} + if user, err := userService.Login(u); err != nil { + global.MAY_LOGGER.Error("登陆失败,用户名不存在或者密码错误", zap.Error(err)) + response.FailWithMessage("用户名不存在或者密码错误", c) + } else { + b.TokenNext(c, *user) + } } else { - b.TokenNext(c, *user) + response.FailWithMessage("验证码错误", c) } } diff --git a/config.yaml b/config.yaml index 1eaae41ec36ee952bfb59ace43aeeac6170ab1d3..b6cc8b9d8be2f63a2b458c3506f866d0694b8b8c 100644 --- a/config.yaml +++ b/config.yaml @@ -32,3 +32,7 @@ jwt: expires-time: 604800 buffer-time: 86400 issuer: 'Shansec' +captcha: + key-long: 6 + img-width: 240 + img-height: 80 \ No newline at end of file diff --git a/config/captcha.go b/config/captcha.go new file mode 100644 index 0000000000000000000000000000000000000000..f629c17f1af851107e5f86f0c823fddae5ab8b66 --- /dev/null +++ b/config/captcha.go @@ -0,0 +1,7 @@ +package config + +type Captcha struct { + KeyLong int `mapstructure:"key-long" json:"key-long" yaml:"key-long"` // 验证码长度 + ImgWidth int `mapstructure:"img-width" json:"img-width" yaml:"img-width"` // 验证码宽度 + ImgHeight int `mapstructure:"img-height" json:"img-height" yaml:"img-height"` // 验证码高度 +} diff --git a/config/config.go b/config/config.go index 1c9cdf747e2c72e6a0604ad9dd3287eb38a5b233..5ce36c588720976992a82e550cf1d9f56a786429 100644 --- a/config/config.go +++ b/config/config.go @@ -5,5 +5,6 @@ type Server struct { Zap Zap `mapstructure:"zap" json:"zap" yaml:"zap"` System System `mapstructure:"system" json:"system" yaml:"system"` // gorm - Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"` + Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"` + Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"` } diff --git a/go.mod b/go.mod index aac151134b34f8be8b2a3ce52e410844921e4032..7d65d7662ba7182f4965d2707a47b912deb58b85 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,7 @@ require ( github.com/go-playground/validator/v10 v10.14.0 // indirect github.com/go-sql-driver/mysql v1.7.0 // indirect github.com/goccy/go-json v0.10.2 // indirect + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect @@ -37,6 +38,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mojocn/base64Captcha v1.3.5 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.0 // indirect @@ -48,6 +50,7 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect golang.org/x/arch v0.3.0 // indirect + golang.org/x/image v0.0.0-20190802002840-cff245a6509b // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/sys v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect diff --git a/go.sum b/go.sum index a0734eba1f205a6e766b354fdefdec9911e4bf0f..595407fe3aca2b1dded37baa37fad541e1e9879b 100644 --- a/go.sum +++ b/go.sum @@ -96,6 +96,8 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -196,6 +198,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0= +github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY= github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM= github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us= @@ -288,6 +292,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= diff --git a/log/server_info.log b/log/server_info.log index a04797a14a2a325cc0099a05b18775f3ff8351fd..903f498d2de2531d34f834aaa4c7157180e92bd7 100644 --- a/log/server_info.log +++ b/log/server_info.log @@ -252,3 +252,6 @@ Shansec24245-24-107 - 100:107:00.695 info E:/minor/Go/src/go-vue-admin/ Shansec26264-26-107 - 100:107:00.623 info E:/minor/Go/src/go-vue-admin/initialize/gorm.go:30 初始化数据库表成功 Shansec26264-26-107 - 100:107:00.652 info E:/minor/Go/src/go-vue-admin/initialize/router.go:32 router register sucess Shansec26264-26-107 - 100:107:00.656 info E:/minor/Go/src/go-vue-admin/core/server.go:27 server run success on {"address": ":8080"} +Shansec27274-27-107 - 100:107:00.818 info E:/minor/Go/src/go-vue-admin/initialize/gorm.go:30 初始化数据库表成功 +Shansec27274-27-107 - 100:107:00.844 info E:/minor/Go/src/go-vue-admin/initialize/router.go:32 router register sucess +Shansec27274-27-107 - 100:107:00.853 info E:/minor/Go/src/go-vue-admin/core/server.go:27 server run success on {"address": ":8080"} diff --git a/model/system/request/sys_user.go b/model/system/request/sys_user.go index 8a6820ab1a14ddb7747cdcd9a45cd9018a61ddd3..81e68f533b2d9145d5af31a486c5455237c23b6e 100644 --- a/model/system/request/sys_user.go +++ b/model/system/request/sys_user.go @@ -16,8 +16,10 @@ type Register struct { // Login structure type Login struct { - Username string `json:"username"` // 用户名 - Password string `json:"password"` // 密码 + Username string `json:"username"` // 用户名 + Password string `json:"password"` // 密码 + Captcha string `json:"captcha"` // 验证码 + CaptchaId string `json:"captchaId"` // 验证码ID } // ChangePassword structure diff --git a/model/system/response/sys_captcha.go b/model/system/response/sys_captcha.go new file mode 100644 index 0000000000000000000000000000000000000000..0fc8b06949d487dd9c05798049f1499cbd26e854 --- /dev/null +++ b/model/system/response/sys_captcha.go @@ -0,0 +1,7 @@ +package response + +type SysCaptchaResponse struct { + CaptchaId string `json:"captchaId"` + PicPath string `json:"picPath"` + CaptchaLength int `json:"captchaLength"` +} diff --git a/router/system/sys_base.go b/router/system/sys_base.go index d38df3d6ab66471c4b028bc358c436d223f645e4..4dea2a97378b6e7eccb360c0b0964ff1cf2e2439 100644 --- a/router/system/sys_base.go +++ b/router/system/sys_base.go @@ -12,9 +12,9 @@ func (b *BaseRouter) InitBaseRouter(Router *gin.RouterGroup) (R gin.IRoutes) { baseRouter := Router.Group("base") baseApi := v1.ApiGroupAlias.SystemApiGroup.BaseApi { - baseRouter.POST("register", baseApi.Register) // 注册 baseRouter.POST("login", baseApi.Login) // 登录 + baseRouter.GET("captcha", baseApi.Captcha) // 验证码获取 } return baseRouter }