当前位置:网站首页>15. User web layer services (III)
15. User web layer services (III)
2022-07-28 11:48:00 【Endless character】
Catalog
One 、 Graphic verification code
1 - Generate image captcha
- Official address :https://mojotv.cn/go/refactor-base64-captcha
- user_web\api\chaptcha.go
package api
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/mojocn/base64Captcha"
"go.uber.org/zap"
)
var store = base64Captcha.DefaultMemStore
func GetCaptcha(ctx *gin.Context) {
driver := base64Captcha.NewDriverDigit(80, 240, 5, 0.7, 80)
cp := base64Captcha.NewCaptcha(driver, store)
id, b64s, err := cp.Generate()
if err != nil {
zap.S().Errorf(" Error generating verification code ,: ", err.Error())
ctx.JSON(http.StatusInternalServerError, gin.H{
"msg": " Error generating verification code ",
})
return
}
ctx.JSON(http.StatusOK, gin.H{
"captchaId": id,
"picPath": b64s,
})
}
- user_web\router\router_base.go
package router
import (
"github.com/gin-gonic/gin"
"web_api/user_web/api"
)
func InitBaseRouter(Router *gin.RouterGroup) {
BaseRouter := Router.Group("base")
{
BaseRouter.GET("captcha", api.GetCaptcha)
}
}
- user_web\initialize\init_router.go
package initialize
import (
"github.com/gin-gonic/gin"
"web_api/user_web/middlewares"
"web_api/user_web/router"
)
func Routers() *gin.Engine {
Router := gin.Default()
// Configure cross domain
Router.Use(middlewares.Cors())
ApiGroup := Router.Group("/u/v1")
router.InitUserRouter(ApiGroup)
router.InitBaseRouter(ApiGroup)
return Router
}

- Online conversion view base64 picture :https://www.qvdv.net/tools/qvdv-img2base64.html

2 - Login and add image verification code
- user_web\forms\form_user.go
package forms
type PassWordLoginForm struct {
Mobile string `form:"mobile" json:"mobile" binding:"required,mobile"` // There are specifications for the format of mobile phone numbers , Customize validator
PassWord string `form:"password" json:"password" binding:"required,min=3,max=20"`
Captcha string `form:"captcha" json:"captcha" binding:"required,min=5,max=5"`
CaptchaId string `form:"captcha_id" json:"captcha_id" binding:"required"`
}
- user_web\api\api_user.go
func PassWordLogin(c *gin.Context) {
// Form validation
passwordLoginForm := forms.PassWordLoginForm{
}
if err := c.ShouldBind(&passwordLoginForm); err != nil {
HandleValidatorError(c, err)
return
}
if store.Verify(passwordLoginForm.CaptchaId, passwordLoginForm.Captcha, false) {
c.JSON(http.StatusBadRequest, gin.H{
"captcha": " Verification code error ",
})
return
}
//... Omit

Two 、 User registration
1 - docker install redis
- Reference address :https://blog.csdn.net/qq23001186/article/details/126023939
- redis Of go drive :https://github.com/go-redis/redis
2 - Alicloud SMS verification code
- user_web\forms\form_sms.go
package forms
type SendSmsForm struct {
Mobile string `form:"mobile" json:"mobile" binding:"required,mobile"` // There are specifications for the format of mobile phone numbers , Customize validator
Type uint `form:"type" json:"type" binding:"required,oneof=1 2"` // Register to send SMS verification code and dynamic verification code, login to send verification code
}
- user_web\router\router_base.go
package router
import (
"github.com/gin-gonic/gin"
"web_api/user_web/api"
)
func InitBaseRouter(Router *gin.RouterGroup) {
BaseRouter := Router.Group("base")
{
BaseRouter.GET("captcha", api.GetCaptcha)
BaseRouter.POST("send_sms", api.SendSms)
}
}
- user_web\api\sms.go
package api
import (
"context"
"fmt"
"math/rand"
"net/http"
"strings"
"time"
"web_api/user_web/forms"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/services/dysmsapi"
"github.com/gin-gonic/gin"
"github.com/go-redis/redis/v8"
"web_api/user_web/global"
)
func GenerateSmsCode(witdh int) string {
// Generate width Length of SMS verification code
numeric := [10]byte{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
r := len(numeric)
rand.Seed(time.Now().UnixNano())
var sb strings.Builder
for i := 0; i < witdh; i++ {
fmt.Fprintf(&sb, "%d", numeric[rand.Intn(r)])
}
return sb.String()
}
func SendSms(ctx *gin.Context) {
sendSmsForm := forms.SendSmsForm{
}
if err := ctx.ShouldBind(&sendSmsForm); err != nil {
HandleValidatorError(ctx, err)
return
}
client, err := dysmsapi.NewClientWithAccessKey("cn-beijing", global.ServerConfig.AliSmsInfo.ApiKey, global.ServerConfig.AliSmsInfo.ApiSecrect)
if err != nil {
panic(err)
}
smsCode := GenerateSmsCode(6)
request := requests.NewCommonRequest()
request.Method = "POST"
request.Scheme = "https" // https | http
request.Domain = "dysmsapi.aliyuncs.com"
request.Version = "2017-05-25"
request.ApiName = "SendSms"
request.QueryParams["RegionId"] = "cn-beijing"
request.QueryParams["PhoneNumbers"] = sendSmsForm.Mobile // cell-phone number
request.QueryParams["SignName"] = " Mu Xue online " // Alibaba cloud verified project name Set up your own
request.QueryParams["TemplateCode"] = "SMS_181850725" // Alibaba cloud's SMS template number Set up your own
request.QueryParams["TemplateParam"] = "{\"code\":" + smsCode + "}" // Verification code content in SMS template Make your own I tried to return directly before , But it failed , add code success .
response, err := client.ProcessCommonRequest(request)
fmt.Print(client.DoAction(request, response))
if err != nil {
fmt.Print(err.Error())
}
// Save the verification code - redis
rdb := redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%d", global.ServerConfig.RedisInfo.Host, global.ServerConfig.RedisInfo.Port),
})
rdb.Set(context.Background(), sendSmsForm.Mobile, smsCode, time.Duration(global.ServerConfig.RedisInfo.Expire)*time.Second)
ctx.JSON(http.StatusOK, gin.H{
"msg": " Send successfully ",
})
}
- yaml: Privacy reasons key and secret Not configured
//user_web\config_debug.yaml
//user_web\config_pro.yaml
name: 'user-web'
port: '8081'
user_srv:
host: '127.0.0.1'
port: '50051'
jwt:
key: 'VYLDYq3&hGWjWqF$K1ih'
sms:
key: ''
secrect: ''
expire: 300
redis:
host: '192.168.124.51'
port: '6379'
3、 ... and 、 User registration interface
- user_web\forms\form_user.go
package forms
type PassWordLoginForm struct {
Mobile string `form:"mobile" json:"mobile" binding:"required,mobile"` // There are specifications for the format of mobile phone numbers , Customize validator
PassWord string `form:"password" json:"password" binding:"required,min=3,max=20"`
Captcha string `form:"captcha" json:"captcha" binding:"required,min=5,max=5"`
CaptchaId string `form:"captcha_id" json:"captcha_id" binding:"required"`
}
type RegisterForm struct {
Mobile string `form:"mobile" json:"mobile" binding:"required,mobile"` // There are specifications for the format of mobile phone numbers , Customize validator
PassWord string `form:"password" json:"password" binding:"required,min=3,max=20"`
Code string `form:"code" json:"code" binding:"required,min=6,max=6"`
}
- user_web\api\api_user.go
func Register(c *gin.Context) {
// User registration
registerForm := forms.RegisterForm{
}
if err := c.ShouldBind(®isterForm); err != nil {
HandleValidatorError(c, err)
return
}
// Verification Code
rdb := redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%d", global.ServerConfig.RedisInfo.Host, global.ServerConfig.RedisInfo.Port),
})
value, err := rdb.Get(registerForm.Mobile).Result()
if err == redis.Nil {
c.JSON(http.StatusBadRequest, gin.H{
"code": " Verification code error ",
})
return
} else {
if value != registerForm.Code {
c.JSON(http.StatusBadRequest, gin.H{
"code": " Verification code error ",
})
return
}
}
user, err := global.UserSrvClient.CreateUser(context.Background(), &proto.CreateUserInfo{
NickName: registerForm.Mobile,
PassWord: registerForm.PassWord,
Mobile: registerForm.Mobile,
})
if err != nil {
zap.S().Errorf("[Register] Inquire about 【 New user failed 】 Failure : %s", err.Error())
HandleGrpcErrorToHttp(err, c)
return
}
j := middlewares.NewJWT()
claims := models.CustomClaims{
ID: uint(user.Id),
NickName: user.NickName,
AuthorityId: uint(user.Role),
StandardClaims: jwt.StandardClaims{
NotBefore: time.Now().Unix(), // Effective time of signature
ExpiresAt: time.Now().Unix() + 60*60*24*30, //30 Days overdue
Issuer: "imooc",
},
}
token, err := j.CreateToken(claims)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"msg": " Generate token Failure ",
})
return
}
c.JSON(http.StatusOK, gin.H{
"id": user.Id,
"nick_name": user.NickName,
"token": token,
"expired_at": (time.Now().Unix() + 60*60*24*30) * 1000,
})
}
- user_web\router\router_user.go
package router
import (
"web_api/user_web/api"
"web_api/user_web/middlewares"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
func InitUserRouter(Router *gin.RouterGroup) {
UserRouter := Router.Group("user")
//UserRouter := Router.Group("user").Use(middlewares.JWTAuth()) // To the whole user Add login verification
zap.S().Info(" Configure user related url")
{
UserRouter.GET("list", middlewares.JWTAuth(), middlewares.IsAdminAuth(), api.GetUserList)
UserRouter.POST("pwd_login", api.PassWordLogin)
UserRouter.POST("register", api.Register)
}
}
- YApi Configure the registration interface

Four 、 Complete source code
边栏推荐
- Quickly deploy mqtt clusters on AWS using terraform
- WPF layout controls are scaled up and down with the window, which is suitable for multi-resolution full screen filling applications
- [general database integrated development environment] Shanghai daoning provides you with Aqua Data Studio downloads, tutorials, and trials
- 中国业务型CDP白皮书 | 爱分析报告
- Outlook suddenly becomes very slow and too laggy. How to solve it
- Leecode8 string conversion integer (ATOI)
- Object to object mapping -automapper
- 什么是WordPress
- The fifth generation verification code of "cloud centered, insensitive and extremely fast" is coming heavily
- Autumn recruit offer harvesters, and take the offers of major manufacturers at will
猜你喜欢

CVPR2020 best paper:对称可变形三维物体的无监督学习

拥抱开源指南

目标检测领域必看的6篇论文

Router firmware decryption idea

Leecode8 string conversion integer (ATOI)

数字孪生轨道交通:“智慧化”监控疏通城市运行痛点
![[half understood] zero value copy](/img/4b/c8140bf7ee4baa094ca3011108d686.gif)
[half understood] zero value copy

从0开发一个自己的npm包

Byte side: how to realize reliable transmission with UDP?

LabVIEW AI visual Toolkit (non Ni vision) download and installation tutorial
随机推荐
AlexNet—论文分析及复现
async await如何实现并发
MySQL (version 8.0.16) command and description
LabVIEW AI视觉工具包(非NI Vision)下载与安装教程
Autumn recruit offer harvesters, and take the offers of major manufacturers at will
Cvpr2021 pedestrian re identification /person re identification paper + summary of open source code
Cvpr2020 best paper: unsupervised learning of symmetric deformable 3D objects
I/O实操之对象流(序列化与反序列化)
Shell (I)
对话庄表伟:开源第一课
【补题日记】[2022牛客暑期多校2]D-Link with Game Glitch
LabVIEW AI visual Toolkit (non Ni vision) download and installation tutorial
Leecode8 string conversion integer (ATOI)
Tiktok programmer confession special code tutorial (how to play Tiktok)
WPF layout controls are scaled up and down with the window, which is suitable for multi-resolution full screen filling applications
consul安装与配置
B2 sub theme / blog b2child sub theme / open source code
mysql(8.0.16版)命令及说明
Google Earth engine - use geetool to download single scene images in batches and retrieve NDSI results with Landsat 8
I want to ask you guys, if there is a master-slave switch when CDC collects mysql, is there any solution