Go+Vue開(kāi)發(fā)一個(gè)線(xiàn)上外賣(mài)應(yīng)用的流程(用戶(hù)名密碼和圖形驗(yàn)證碼)
圖形化驗(yàn)證碼生成和驗(yàn)證
功能介紹
在使用用戶(hù)名和密碼登錄功能時(shí),需要填寫(xiě)驗(yàn)證碼,驗(yàn)證碼是以圖形化的方式進(jìn)行獲取和展示的。
驗(yàn)證碼使用原理
驗(yàn)證碼的使用流程和原理為:在服務(wù)器端負(fù)責(zé)生成圖形化驗(yàn)證碼,并以數(shù)據(jù)流的形式供前端訪(fǎng)問(wèn)獲取,同時(shí)將生成的驗(yàn)證碼存儲(chǔ)到全局的緩存中,在本案例中,我們使用redis作為全局緩存,并設(shè)置緩存失效時(shí)間。當(dāng)用戶(hù)使用用戶(hù)名和密碼進(jìn)行登錄時(shí),進(jìn)行驗(yàn)證碼驗(yàn)證。驗(yàn)證通過(guò)即可繼續(xù)進(jìn)行登錄。
驗(yàn)證碼庫(kù)安裝
借助開(kāi)源的驗(yàn)證碼工具庫(kù)可以生成驗(yàn)證碼。
首先,安裝開(kāi)源的驗(yàn)證碼生成庫(kù):
go get -u github.com/mojocn/base64Captcha go get github.com/mojocn/base64Captcha@v1.2.2
驗(yàn)證碼代碼示例
在下載后的base64Captcha庫(kù)的目錄中,可以看到有_example和_example_redis兩個(gè)目錄。第一個(gè)example是用于演示生成驗(yàn)證碼和驗(yàn)證碼的示例代碼。
按照示例代碼的說(shuō)明,運(yùn)行程序并在瀏覽器進(jìn)行端口訪(fǎng)問(wèn):
go run main.go //瀏覽器中訪(fǎng)問(wèn):http://localhost:8777
如下圖所示:
通過(guò)自定義配置,可以選擇不同的生成驗(yàn)證碼的參數(shù),并刷新驗(yàn)證碼,同時(shí)還可以對(duì)驗(yàn)證碼進(jìn)行驗(yàn)證。
通過(guò)exmaple目錄下的main.go程序可以看到生成驗(yàn)證碼和驗(yàn)證驗(yàn)證碼的邏輯,此處不再贅述。
項(xiàng)目集成驗(yàn)證碼生成和Redis緩存
通常來(lái)說(shuō),驗(yàn)證碼都是有一定的實(shí)效性的,過(guò)期驗(yàn)證碼也就無(wú)效了。
因此,我們考慮在項(xiàng)目中引入Redis作為數(shù)據(jù)緩存。當(dāng)驗(yàn)證碼生成后,將驗(yàn)證碼存放在Redis中,并根據(jù)配置文件對(duì)Redis進(jìn)行設(shè)置。
安裝go-redis庫(kù)
在項(xiàng)目中使用redis,需要安裝go-redis庫(kù),可以在https://github.com/go-redis/redis中查看如何下載go-redis和配置。
增加Redis配置
在配置文件app.json中新增redis配置:
"redis_config": { "addr": "127.0.0.1", "port": "6379", "password": "", "db": 0 }
同時(shí),新增RedisConfig結(jié)構(gòu)體定義,如下所示:
type RedisConfig struct { Addr string `json:"addr"` Port string `json:"port"` Password string `json:"password"` Db int `json:"db"` }
Redis初始化操
進(jìn)行了redis配置以后,需要對(duì)redis進(jìn)行初始化??梢苑庋bredis初始化操作函數(shù)如下所示:
type RedisStore struct { redisClient *redis.Client } var Redis *redis.Client func InitRediStore() *RedisStore { config := GetConfig().RedistConfig Redis = redis.NewClient(&redis.Options{ Addr: config.Addr + ":" + config.Port, Password: config.Password, DB: config.Db, }) customeStore := &RedisStore{Redis} base64Captcha.SetCustomStore(customeStore) return customeStore }
同時(shí),為customeStore提供Set和Get兩個(gè)方法,如下所示:
func (cs *RedisStore) Set(id string, value string) { err := cs.redisClient.Set(id, value, time.Minute*2).Err() if err != nil { log.Println(err.Error()) } } func (cs *RedisStore) Get(id string, clear bool) string { val, err := cs.redisClient.Get(id).Result() if err != nil { toolbox.Error(err.Error()) return "" } if clear { err := cs.redisClient.Del(id).Err() if err != nil { toolbox.Error(err.Error()) return "" } } return val }
對(duì)Redis進(jìn)行初始化和定義完成以后,需要在main中調(diào)用一下初始化操作InitRediStore:
func main(){ ... //Redis配置初始化 toolbox.InitRediStore() ... }
驗(yàn)證碼生成和驗(yàn)證
本項(xiàng)目中采用的驗(yàn)證碼的生成庫(kù)支持三種驗(yàn)證碼,分別是:audio,character和digit。我們選擇character類(lèi)型。
定義Captcha.go文件,實(shí)現(xiàn)驗(yàn)證碼的生成和驗(yàn)證碼函數(shù)的定義。在進(jìn)行驗(yàn)證碼生成時(shí),默認(rèn)提供驗(yàn)證碼的配置,并生成驗(yàn)證碼后返回給客戶(hù)端瀏覽器。如下是生成驗(yàn)證碼的函數(shù)定義:
//生成驗(yàn)證碼 func GenerateCaptchaHandler(ctx *gin.Context) { //圖形驗(yàn)證碼的默認(rèn)配置 parameters := base64Captcha.ConfigCharacter{ Height: 60, Width: 240, Mode: 3, ComplexOfNoiseText: 0, ComplexOfNoiseDot: 0, IsUseSimpleFont: true, IsShowHollowLine: false, IsShowNoiseDot: false, IsShowNoiseText: false, IsShowSlimeLine: false, IsShowSineLine: false, CaptchaLen: 4, BgColor: &color.RGBA{ R: 3, G: 102, B: 214, A: 254, }, } captchaId, captcaInterfaceInstance := base64Captcha.GenerateCaptcha("", parameters) base64blob := base64Captcha.CaptchaWriteToBase64Encoding(captcaInterfaceInstance) captchaResult := CaptchaResult{Id: captchaId, Base64Blob: base64blob} // 設(shè)置json響應(yīng) tool.Success(ctx, map[string]interface{}{ "captcha_result": captchaResult, }) }
驗(yàn)證碼接口解析
圖形化驗(yàn)證碼是用戶(hù)名和密碼登錄功能的數(shù)據(jù),屬于Member模塊。因此在MemberController中增加獲取驗(yàn)證碼的接口解析,如下:
func (mc *MemberController) Router(engine *gin.Engine){ //獲取驗(yàn)證碼 engine.GET("/api/captcha", mc.captcha) }
測(cè)試結(jié)果如下,能夠正常獲取到數(shù)據(jù):
驗(yàn)證碼的驗(yàn)證
同理,可以對(duì)客戶(hù)端提交的驗(yàn)證碼進(jìn)行驗(yàn)證,具體實(shí)現(xiàn)邏輯如下:
//驗(yàn)證驗(yàn)證碼是否正確 func CaptchaVerify(r *http.Request) bool { var captchaResult CaptchaResult //接收客戶(hù)端發(fā)送來(lái)的請(qǐng)求參數(shù) decoder := json.NewDecoder(r.Body) err := decoder.Decode(&captchaResult) if err != nil { log.Println(err) } defer r.Body.Close() //比較圖像驗(yàn)證碼 verifyResult := base64Captcha.VerifyCaptcha(captchaResult.Id, captchaResult.VertifyValue) return verifyResult }
用戶(hù)名密碼登錄功能開(kāi)發(fā)
功能介紹
上節(jié)課已經(jīng)完成了驗(yàn)證碼的生成,本節(jié)課來(lái)開(kāi)發(fā)用戶(hù)名、密碼和驗(yàn)證碼登錄功能。
接口和參數(shù)解析定義
用戶(hù)名和密碼的登錄接口為:
/api/login_pwd
接口請(qǐng)求類(lèi)型為POST,接口參數(shù)有三個(gè):name,pwd,captcha。其中:captcha為驗(yàn)證碼。
定義登錄參數(shù)結(jié)構(gòu)體LoginParam:
//用戶(hù)名,密碼和驗(yàn)證碼登錄 type LoginParam struct { Name string `json:"name"` //用戶(hù)名 Password string `json:"pwd"` //密碼 Id string `json:"id"`// captchaId 驗(yàn)證碼ID Value string `json:"value"` //驗(yàn)證碼 }
邏輯控制層實(shí)現(xiàn)登錄流程控制
方法解析
在MemberController.go文件中,編寫(xiě)方法用于處理用戶(hù)名密碼登錄的解析方法如下所示:
func (mc *MemberController) Router(engine *gin.Engine){ engine.POST("/api/login_pwd", mc.nameLogin) }
登錄流程編程實(shí)現(xiàn)
定義新的func并命名為nameLogin,實(shí)現(xiàn)登錄流程邏輯控制:
//用戶(hù)名、密碼登錄 func (mc *MemberController) nameLogin(context *gin.Context) { //1、登錄參數(shù)解析 var loginParam param.LoginParam err := toolbox.Decode(context.Request.Body, &loginParam) if err != nil { toolbox.Failed(context, "參數(shù)解析失敗") return } //2、驗(yàn)證驗(yàn)證碼 service := impl.NewMemberService() validate := toolbox.CaptchaVerify(loginParam.Id, loginParam.Value) fmt.Println(validate) if !validate { toolbox.ValidateFailed(context, "驗(yàn)證碼不正確, 請(qǐng)重新驗(yàn)證 ") return } //3、登錄 member := service.Login(loginParam.Name, loginParam.Password) if member.Id == 0 { toolbox.Failed(context, "登錄失敗") return } toolbox.Success(context, &member) }
在控制層的nameLogin方法中,主要有3個(gè)邏輯處理:
- 1、通過(guò)*gin.Context解析請(qǐng)求登錄請(qǐng)求攜帶的參數(shù)。
- 2、從攜帶的參數(shù)中得到提交的驗(yàn)證碼數(shù)據(jù),調(diào)用驗(yàn)證碼判斷驗(yàn)證碼方法對(duì)驗(yàn)證碼進(jìn)行判斷。驗(yàn)證碼驗(yàn)證失敗或者驗(yàn)證碼失效,直接返回登錄失敗信息。
- 3、使用用戶(hù)名、密碼參數(shù)進(jìn)行登錄,判斷登錄結(jié)果。如果登錄成功,返回用戶(hù)登錄信息,否則返回登錄失敗。
Service層實(shí)現(xiàn)
在功能服務(wù)層的MemberService文件中,定義和實(shí)現(xiàn)用戶(hù)名密碼登錄的Login方法。詳細(xì)實(shí)現(xiàn)如下:
//用戶(hù)登錄: 如果沒(méi)有登錄過(guò),自動(dòng)進(jìn)行登錄 func (msi *MemberServiceImpl) Login(name string, password string) *model.Member { dao := impl.NewMemberDao() //1、先查詢(xún)是否已經(jīng)存在該用戶(hù) member := dao.Query(name, password) if member.Id != 0 { return member } user := model.Member{} user.UserName = name user.Password = toolbox.EncoderSha256(password) user.RegisterTime = time.Now().Unix() result := dao.InsertMember(user) user.Id = result return &user }
在service層的Login方法中,分為兩步邏輯判斷:
1、先查詢(xún)是否已經(jīng)存在該用戶(hù),如果該用于已經(jīng)存在,則直接將查詢(xún)到的用戶(hù)信息返回。
2、如果用戶(hù)不存在,將用戶(hù)信息作為新記錄保存到數(shù)據(jù)庫(kù)中,新增一條記錄。并返回用戶(hù)信息。
最后,涉及到操作數(shù)據(jù)庫(kù)的兩個(gè)方法分別是:Query和InsertMember方法。InsertMember方法之前已經(jīng)編寫(xiě)過(guò),只需要重新編寫(xiě)一個(gè)Query方法即可,Query方法實(shí)現(xiàn)如下所示:
//根據(jù)用戶(hù)名和密碼查詢(xún)用戶(hù)記錄 func (mdi *MemberDaoImpl) Query(name string, password string) *model.Member { var member model.Member password = toolbox.EncoderSha256(password) _, err := mdi.Where(" user_name = ? and password = ? ", name, password).Get(&member) if err != nil { toolbox.Error(err.Error()) return nil } return &member }
到此這篇關(guān)于Go+Vue開(kāi)發(fā)一個(gè)線(xiàn)上外賣(mài)應(yīng)用(用戶(hù)名密碼和圖形驗(yàn)證碼)的文章就介紹到這了,更多相關(guān)Go線(xiàn)上外賣(mài)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用golang編寫(xiě)一個(gè)并發(fā)工作隊(duì)列
這篇文章主要介紹了使用golang編寫(xiě)一個(gè)并發(fā)工作隊(duì)列的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-05-05Go語(yǔ)言實(shí)現(xiàn)常見(jiàn)限流算法的示例代碼
計(jì)數(shù)器、滑動(dòng)窗口、漏斗算法、令牌桶算法是我們常見(jiàn)的幾個(gè)限流算法,本文將依次用Go語(yǔ)言實(shí)現(xiàn)這幾個(gè)限流算法,感興趣的可以了解一下2023-05-05Air實(shí)現(xiàn)Go程序?qū)崟r(shí)熱重載使用過(guò)程解析示例
這篇文章主要為大家介紹了Air實(shí)現(xiàn)Go程序?qū)崟r(shí)熱重載使用過(guò)程解析示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04go單體日志采集zincsearch方案實(shí)現(xiàn)
這篇文章主要為大家介紹了go單體日志采集zincsearch方案實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07利用go-zero在Go中快速實(shí)現(xiàn)JWT認(rèn)證的步驟詳解
這篇文章主要介紹了如何利用go-zero在Go中快速實(shí)現(xiàn)JWT認(rèn)證,本文分步驟通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2020-10-10