当前位置:网站首页>Go language web development series 25: Gin framework: using MD5 to verify the signature for the interface station
Go language web development series 25: Gin framework: using MD5 to verify the signature for the interface station
2022-07-03 13:47:00 【Lao Liu, you are so awesome】
One , Libraries used for installation
1,gin In the framework of github The address of :
https://github.com/gin-gonic/gin
2, Install... From the command line :
[email protected]:/data/go/ginhello# go get -u github.com/gin-gonic/[email protected]
explain : Liu Hongdi's go The forest is a focus golang The blog of ,
Address :https://blog.csdn.net/weixin_43881017
explain : author : Liu Hongdi mailbox : [email protected]
Two , Information about the demonstration project
1, Project address :
https://github.com/liuhongdi/digv25
2, Functional specifications : Demonstrate adding signature verification for the interface station , Avoid attacks on interfaces
3, Project structure : Pictured :
3、 ... and ,go Code instructions
1,controller/userController.go
package controller
import (
"github.com/gin-gonic/gin"
"github.com/liuhongdi/digv25/global"
)
type UserController struct{}
func NewUserController() UserController {
return UserController{}
}
// The user login
func (g *UserController) Login(c *gin.Context) {
result := global.NewResult(c)
result.Success("success");
return
}
2,global/constants.go
package global
var (
SignAppId string = "wap" //app id
SignAppSecret string = "30c722c6acc64306a88dd93a814c9f0a" //app secret
SignApiVersion string = "1.0" //api version
SignExpire int64 = 180 // Expiration time ,180 second
)
3,middleware/sign.go
package middleware
import (
"github.com/gin-gonic/gin"
"github.com/liuhongdi/digv25/global"
"github.com/liuhongdi/digv25/pkg/sign"
"regexp"
)
// Current limiter
func SignMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// Check whether the current url
exclude := regexp.MustCompile("/static/*")
path := c.Request.RequestURI
//fmt.Println("path:"+path)
if exclude != nil && exclude.MatchString(path) {
c.Next()
return
}
// from header To obtain parameters
appId := c.Request.Header.Get("appId")
timestamp := c.Request.Header.Get("timestamp")
signcli := c.Request.Header.Get("sign")
nonce := c.Request.Header.Get("nonce")
// Verify that the signature is correct
err := sign.VerifySign(appId,timestamp,signcli,nonce,global.SignAppId,global.SignAppSecret,global.SignApiVersion,global.SignExpire)
if (err != nil) {
resultRes := global.NewResult(c)
resultRes.Error(2004,err.Error())
return
} else {
//fmt.Println("sign passed")
c.Next()
return
}
}
}
4,pkg/md5/md5.go
package md5
import (
"crypto/md5"
"encoding/hex"
)
// return md5 result
func MD5(str string) string {
s := md5.New()
s.Write([]byte(str))
return hex.EncodeToString(s.Sum(nil))
}
5,pkg/sign/sign.go
package sign
import (
"errors"
"github.com/liuhongdi/digv25/pkg/md5"
"strconv"
"time"
)
// Verify the signature
func VerifySign(appId,timestamp,sign,nonce,serverAppId,serverAppSecret,serverApiVersion string,signExpire int64) error {
// verification appid
if (serverAppId != appId) {
return errors.New("appId Error")
}
// Validation expiration time
timestampNow := time.Now().Unix()
//fmt.Println("now:")
//fmt.Println(timestampNow)
tsInt, _ := strconv.ParseInt(timestamp, 10, 64)
//fmt.Println("timeint:")
//fmt.Println(tsInt)
if tsInt > timestampNow || timestampNow - tsInt >= signExpire {
return errors.New("timestamp Error")
}
// Get the right sign For inspection
origin := appId + serverAppSecret + timestamp + nonce + serverApiVersion;
signEcrypt := md5.MD5(origin);
if (signEcrypt != sign) {
return errors.New("sign Error")
}
// No mistakes , return
return nil
}
6,router/router.go
package router
import (
"github.com/gin-gonic/gin"
"github.com/liuhongdi/digv25/controller"
"github.com/liuhongdi/digv25/global"
"github.com/liuhongdi/digv25/middleware"
"log"
"net/http"
"runtime/debug"
)
func Router() *gin.Engine {
router := gin.Default()
// Handling exceptions
router.NoRoute(HandleNotFound)
router.NoMethod(HandleNotFound)
router.Use(middleware.SignMiddleware())
router.Use(Recover)
//static
router.StaticFS("/static", http.Dir("/data/liuhongdi/digv25/static"))
// Path mapping :index
indexc:=controller.NewIndexController()
router.GET("/index/index", indexc.Index);
// Path mapping :user
userc:=controller.NewUserController()
router.POST("/user/login", userc.Login);
return router
}
func HandleNotFound(c *gin.Context) {
global.NewResult(c).Error(404," Resource not found ")
return
}
func Recover(c *gin.Context) {
defer func() {
if r := recover(); r != nil {
// Print error stack information
log.Printf("panic: %v\n", r)
debug.PrintStack()
global.NewResult(c).Error(500," Server internal error ")
}
}()
// Finished loading defer recover, Continue with subsequent interface calls
c.Next()
}
7,static/form.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" language="JavaScript" src="jquery-1.6.2.min.js"></script>
<script type="text/javascript" language="JavaScript" src="md5.js"></script>
</head>
<body>
<a href="javascript:login('right')">login(right)</a><br/>
<a href="javascript:login('error')">login(error)</a><br/>
<script>
//vars
var appId="wap";
var version="1.0";
// obtain sign
function getsign(appSecret,timestamp,nonce) {
var origin = appId + appSecret + timestamp + nonce + version;
console.log("origin:"+origin);
var sign = hex_md5(origin);
return sign;
}
// visit login This api
// explain : Here are just examples , stay ios/android In development ,appSecret Compile and save in binary form
function login(isright) {
//right secret
var appSecret_right="30c722c6acc64306a88dd93a814c9f0a";
//error secret
var appSecret_error="aabbccdd";
var timestamp = parseInt((new Date()).getTime()/1000);
var nonce = Math.floor(Math.random()*8999)+1000;
var sign = "";
if (isright == 'right') {
sign = getsign(appSecret_right,timestamp,nonce);
} else {
sign = getsign(appSecret_error,timestamp,nonce);
}
var postdata = {
username:"a",
password:"b"
}
$.ajax({
type:"POST",
url:"/user/login",
data:postdata,
// Return the format of the data
datatype: "json",
// Top note function before request
beforeSend: function(request) {
request.setRequestHeader("appId", appId);
request.setRequestHeader("timestamp", timestamp);
request.setRequestHeader("sign", sign);
request.setRequestHeader("nonce", nonce);
},
// Base note function after successful return
success:function(data){
//alert(data.code);
if (data.code == 0) {
alert(' Successful visit ');
} else {
alert("failed:"+data.msg);
}
},
// Base note
complete: function(XMLHttpRequest, textStatus){
//complete
},
// Call the function executed in error
error: function(){
// Request error handling
}
});
}
</script>
</body>
</html>
8, Other related codes can be accessed github
Four , Effect test
1, visit html page :
http://127.0.0.1:8080/static/form.html
return :
2, Click the respectively : Test and verify whether it is effective :
Click on error When linking :
5、 ... and , View the version of the library :
module github.com/liuhongdi/digv25
go 1.15
require (
github.com/gin-gonic/gin v1.6.3
)
边栏推荐
- Go language unit test 3: go language uses gocovey library to do unit test
- When updating mysql, the condition is a query
- JVM系列——概述,程序计数器day1-1
- Can newly graduated European college students get an offer from a major Internet company in the United States?
- Brief analysis of tensorboard visual processing cases
- Task6: using transformer for emotion analysis
- php 迷宫游戏
- ThreadPoolExecutor realizes multi-threaded concurrency and obtains the return value (elegant and concise way)
- Sequence table (implemented in C language)
- Unable to stop it, domestic chips have made another breakthrough, and some links have reached 4nm
猜你喜欢
SQL Injection (AJAX/JSON/jQuery)
双向链表(我们只需要关注插入和删除函数)
KEIL5出现中文字体乱码的解决方法
Setting up remote links to MySQL on Linux
物联网毕设 --(STM32f407连接云平台检测数据)
rxjs Observable filter Operator 的实现原理介绍
MySQL functions and related cases and exercises
The shortage of graphics cards finally came to an end: 3070ti for more than 4000 yuan, 2000 yuan cheaper than the original price, and 3090ti
Flutter dynamic | fair 2.5.0 new version features
[technology development-24]: characteristics of existing IOT communication technology
随机推荐
研发团队资源成本优化实践
[技术发展-24]:现有物联网通信技术特点
json序列化时案例总结
pytorch 载入历史模型时更换gpu卡号,map_location设置
使用Tensorflow进行完整的深度神经网络CNN训练完成图片识别案例2
Unity render streaming communicates with unity through JS
SQL Injection (GET/Search)
When updating mysql, the condition is a query
MySQL constraints
Unable to stop it, domestic chips have made another breakthrough, and some links have reached 4nm
[développement technologique - 24]: caractéristiques des technologies de communication Internet des objets existantes
JS 将伪数组转换成数组
Road construction issues
Field problems in MySQL
[quantitative trading] permanent portfolio, turtle trading rules reading, back testing and discussion
【被动收入如何挣个一百万】
Red Hat Satellite 6:更好地管理服务器和云
Kivy教程之 盒子布局 BoxLayout将子项排列在垂直或水平框中(教程含源码)
掌握Cypress命令行选项,是真正掌握Cypress的基础
Students who do not understand the code can also send their own token, which is easy to learn BSC