一、图形验证码
1 - 生成图片验证码
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 ( "生成验证码错误,: " , err. Error ( ) )
ctx. JSON ( http. StatusInternalServerError, gin. H{
"msg" : "生成验证码错误" ,
} )
return
}
ctx. JSON ( http. StatusOK, gin. H{
"captchaId" : id,
"picPath" : b64s,
} )
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
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 ( )
Router. Use ( middlewares. Cors ( ) )
ApiGroup := Router. Group ( "/u/v1" )
router. InitUserRouter ( ApiGroup)
router. InitBaseRouter ( ApiGroup)
return Router
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
2 - 登录添加图片验证码
user_web\forms\form_user.go
package forms
type PassWordLoginForm struct {
Mobile string `form:"mobile" json:"mobile" binding:"required,mobile"`
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"`
}
func PassWordLogin ( c * gin. Context) {
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" : "验证码错误" ,
} )
return
}
二、用户注册
1 - docker安装redis
2 - 阿里云短信验证码
user_web\forms\form_sms.go
package forms
type SendSmsForm struct {
Mobile string `form:"mobile" json:"mobile" binding:"required,mobile"`
Type uint `form:"type" json:"type" binding:"required,oneof=1 2"`
}
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)
}
}
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 {
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"
request. Domain = "dysmsapi.aliyuncs.com"
request. Version = "2017-05-25"
request. ApiName = "SendSms"
request. QueryParams[ "RegionId" ] = "cn-beijing"
request. QueryParams[ "PhoneNumbers" ] = sendSmsForm. Mobile
request. QueryParams[ "SignName" ] = "慕学在线"
request. QueryParams[ "TemplateCode" ] = "SMS_181850725"
request. QueryParams[ "TemplateParam" ] = "{\"code\":" + smsCode + "}"
response, err := client. ProcessCommonRequest ( request)
fmt. Print ( client. DoAction ( request, response) )
if err != nil {
fmt. Print ( err. Error ( ) )
}
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" : "发送成功" ,
} )
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
//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'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
三、用户注册接口
user_web\forms\form_user.go
package forms
type PassWordLoginForm struct {
Mobile string `form:"mobile" json:"mobile" binding:"required,mobile"`
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"`
PassWord string `form:"password" json:"password" binding:"required,min=3,max=20"`
Code string `form:"code" json:"code" binding:"required,min=6,max=6"`
}
func Register ( c * gin. Context) {
registerForm := forms. RegisterForm{ }
if err := c. ShouldBind ( & registerForm) ; err != nil {
HandleValidatorError ( c, err)
return
}
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" : "验证码错误" ,
} )
return
} else {
if value != registerForm. Code {
c. JSON ( http. StatusBadRequest, gin. H{
"code" : "验证码错误" ,
} )
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] 查询 【新建用户失败】失败: %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 ( ) ,
ExpiresAt: time. Now ( ) . Unix ( ) + 60 * 60 * 24 * 30 ,
Issuer: "imooc" ,
} ,
}
token, err := j. CreateToken ( claims)
if err != nil {
c. JSON ( http. StatusInternalServerError, gin. H{
"msg" : "生成token失败" ,
} )
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 ,
} )
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
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" )
zap. S ( ) . Info ( "配置用户相关的url" )
{
UserRouter. GET ( "list" , middlewares. JWTAuth ( ) , middlewares. IsAdminAuth ( ) , api. GetUserList)
UserRouter. POST ( "pwd_login" , api. PassWordLogin)
UserRouter. POST ( "register" , api. Register)
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
YApi配置注册接口
四、完整源码
mxshop_srvsV5.0.rar