当前位置:网站首页>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
边栏推荐
- In order to ensure the normal operation of fire-fighting equipment in large buildings, the power supply monitoring system of fire-fighting equipment plays a key role
- Digital twin rail transit: "intelligent" monitoring to clear the pain points of urban operation
- CVPR2020 best paper:对称可变形三维物体的无监督学习
- P5472 [NOI2019] 斗主地(期望、数学)
- R语言-用于非平衡数据集的一些度量指标
- consul安装与配置
- Solutions to the disappearance of Jupiter, spyder, Anaconda prompt and navigator shortcut keys
- 业务可视化-让你的流程图'Run'起来(4.实际业务场景测试)
- 【补题日记】[2022牛客暑期多校2]D-Link with Game Glitch
- 从0开发一个自己的npm包
猜你喜欢

Boutique scheme | Haitai Fangyuan full stack data security management scheme sets a "security lock" for data

Cvpr2021 pedestrian re identification /person re identification paper + summary of open source code

CVPR2020 best paper:对称可变形三维物体的无监督学习
![ASP. Net core 6 framework unveiling example demonstration [29]: building a file server](/img/90/40869d7c03f09010beb989af07e2f0.png)
ASP. Net core 6 framework unveiling example demonstration [29]: building a file server

Refresh your understanding of redis cluster

PFP会是数字藏品的未来吗?

In order to ensure the normal operation of fire-fighting equipment in large buildings, the power supply monitoring system of fire-fighting equipment plays a key role

中国业务型CDP白皮书 | 爱分析报告

Are interviews all about memorizing answers?

A hundred flowers bloom in data analysis engines. Why invest heavily in Clickhouse?
随机推荐
[geek challenge 2019] babysql-1 | SQL injection
Digital twin rail transit: "intelligent" monitoring to clear the pain points of urban operation
Network communication protocol classification and IP address
Dialogue with Zhuang biaowei: the first lesson of open source
R language uses LM function to build regression model and regression model for transformed data (for example, it is necessary to build regression model for X and y, but they have no linear relationshi
DNS series (III): how to avoid DNS spoofing
PHP detects whether the URL URL link is normally accessible
如何让照片中的人物笑起来?HMS Core视频编辑服务一键微笑功能,让人物笑容更自然
【补题日记】[2022杭电暑期多校2]K-DOS Card
Cvpr2020 best paper: unsupervised learning of symmetric deformable 3D objects
Google Earth engine - use geetool to download single scene images in batches and retrieve NDSI results with Landsat 8
jar 包内文件的遍历以及文件的拷贝
Display line number under VIM command [easy to understand]
R language uses LM function to build regression model, uses the augmented function of bloom package to store the model results in dataframe, and uses ggplot2 to visualize the regression residual diagr
Object stream of i/o operation (serialization and deserialization)
[applet] how to notify users of wechat applet version update?
What is the process of switching c read / write files from user mode to kernel mode?
Six papers that must be seen in the field of target detection
Let me think about Linear Algebra: a summary of basic learning of linear algebra
[collection] Advanced Mathematics: Capriccio of stars