Browse Source

验证参数

wangshan 7 years ago
parent
commit
b67732c1aa

BIN
pkg/windows_amd64/apiservice/oamanager.a


+ 198 - 33
src/apiservice/oamanager/oamanager.go

@@ -2,9 +2,23 @@ package oamanager
 
 import (
 	"apiservice/tools"
+	"bytes"
+	"compress/gzip"
+	"crypto/hmac"
+	"crypto/sha1"
+	"encoding/base64"
+	"encoding/json"
+	"hash"
+	"io"
 	"log"
+	"net"
+	"net/http"
+	"net/url"
 	"qfw/util"
+	"qfw/util/redis"
+	"sort"
 	"strconv"
+	"strings"
 	"time"
 
 	"github.com/go-xweb/xweb"
@@ -12,17 +26,19 @@ import (
 
 type Oamanager struct {
 	*xweb.Action
-	openAction xweb.Mapper `xweb:"/open"`
+	//openAction xweb.Mapper `xweb:"/open"`
+	index xweb.Mapper `xweb:"/"`
 }
 
+var mongodb = tools.MQFW
+
 func init() {
 	xweb.AddAction(&Oamanager{})
 }
 
-var mongodb = tools.MQFW
-
 const (
-	LIMIT_TIME  = 300
+	LIMIT_TIME  = 3000 //链接超时时间
+	LIMIT_COUNT = 3000 //每天接口限制
 	REDISDB     = "jyOpenAPI"
 	CODE_E1     = 40000
 	MSG_E1      = "签名错误"
@@ -34,48 +50,197 @@ const (
 	MSG_E4      = "调用接口超过限制"
 	CODE_E5     = 40004
 	MSG_E5      = "内部错误"
-	CODE_ERR_E0 = 40005
-	MSG_ERR_E   = "IP未授权"
+	CODE_E6     = 40005
+	MSG_E6      = "IP未授权"
 	MSG_SUCCESS = "请求成功"
 )
 
-func (o *Oamanager) OpenAction() {
+var APPID, SECRET string
+
+//
+func (o *Oamanager) Index() error {
+	return o.Render("/pc/article.html")
+}
+
+//
+func OpenAction(w http.ResponseWriter, r *http.Request) {
 	rData := make(map[string]interface{})
+	var rCode = 0
+	var rMsg = ""
 	defer util.Catch()
 	//if o.Method() == "POST"
-
 	var (
-		//action    = "" //o.GetString("action")
-		//keyword   = "" //o.GetString("keyword")
-		appid   = o.GetString("appid")
-		secret  = o.GetString("secret")
-		pagenum = "" //o.GetString("pagenum")
-		//signature = "" //o.GetString("signature")
-		ttamp     = time.Now().Unix()
-		timestamp int64
+		action       = r.FormValue("action")
+		keyword      = r.FormValue("keyword")
+		appid        = r.FormValue("appid")
+		pagenum, _   = strconv.Atoi(r.FormValue("pagenum"))
+		signature    = r.FormValue("signature")
+		ttamp        = time.Now().Unix()
+		timestamp, _ = strconv.Atoi(r.FormValue("timestamp"))
 	)
-	if appid == "" || secret == "" || o.GetString("timestamp") == "" {
-		rData["code"] = CODE_E1
+	if appid == "" || action == "" || keyword == "" || timestamp == 0 { //|| signature == ""
+		rCode = CODE_E1 //签名错误
+		rMsg = "签名错误"
 	} else {
-		if pagenum == "" {
-			pagenum = "1"
+		ttmp1 := strconv.Itoa(timestamp)
+		ttmp2, _ := strconv.ParseInt(ttmp1, 10, 64)
+		if (ttamp - ttmp2) > LIMIT_TIME {
+			rCode = CODE_E3 //签名过期
+			rMsg = "签名过期"
+		} else {
+			apicount := redis.GetInt(REDISDB, "jyopenapi-"+appid)
+			if apicount > LIMIT_COUNT {
+				rCode = CODE_E4 //调用接口超过限制
+				rMsg = "调用接口超过限制"
+			} else {
+				if pagenum == 0 {
+					pagenum = 1
+				}
+				res, _ := mongodb.FindOneByField("user", &map[string]interface{}{
+					"appid": appid,
+				}, nil)
+				if len(*res) > 0 {
+					comip := GetAPIIP(r)
+					log.Println((*res)["userip"], "---", comip)
+					if (*res)["userip"] == comip {
+						APPID = appid
+						SECRET = util.ObjToString((*res)["secret"])
+						sign := GET(action, [][]string{
+							[]string{"keyword", keyword},
+							[]string{"appid", appid},
+							[]string{"timestamp", strconv.Itoa(timestamp)},
+							[]string{"pagenum", strconv.Itoa(pagenum)},
+						})
+						log.Println(signature, "-1212--:", sign)
+						if sign == signature {
+							if action == "getdata" {
+								rData["data"] = GetData(pagenum, keyword)
+							}
+						} else {
+							rCode = CODE_E1 //签名错误
+							rMsg = "签名错误"
+						}
+					} else {
+					}
+				} else {
+					rCode = CODE_E1 //签名错误
+					rMsg = "签名错误"
+				}
+			}
+		}
+	}
+	log.Println(rData, "---", rCode, "-", rMsg)
+	if rCode == 0 {
+		w.Header().Set("Accept-Charset", "utf-8")
+		w.Header().Set("Content-Type", "application/json")
+		w.Header().Set("Content-Encoding", "gzip")
+		gz := gzip.NewWriter(w)
+		defer gz.Close()
+		err := json.NewEncoder(gz).Encode(rData)
+		if err != nil {
+			log.Println("writejson err", err.Error())
+		}
+	} else {
+		w.Write([]byte("{\"code\":" + strconv.Itoa(rCode) + "}"))
+	}
+}
+
+//
+func GetData(pagenum int, keyword string) {
+
+}
+
+//获取请求ip
+func GetAPIIP(req *http.Request) string {
+	if req == nil {
+		return ""
+	}
+	ip_for := req.Header.Get("x-forwarded-for")
+	ip_client := req.Header.Get("http_client_ip")
+	ip_addr := req.Header.Get("Remote_addr")
+	un := "unknown"
+	if (ip_for != un) && (len(strings.TrimSpace(ip_for)) > 0) {
+		return ip_for
+	}
+	if (ip_client != un) && (len(strings.TrimSpace(ip_client)) > 0) {
+		return ip_client
+	}
+	if (ip_addr != un) && (len(strings.TrimSpace(ip_addr)) > 0) {
+		return ip_addr
+	}
+	ip, _, _ := net.SplitHostPort(req.RemoteAddr)
+	return ip
+}
+
+//GET请求
+func GET(action string, param [][]string) (signedStr string) {
+	ps := &paramSorter{[]string{}, []string{}}
+	ps.Keys = append(ps.Keys, "Action")
+	ps.Vals = append(ps.Vals, action)
+	if len(param) > 0 {
+		for _, v := range param {
+			ps.Keys = append(ps.Keys, v[0])
+			ps.Vals = append(ps.Vals, v[1])
 		}
-		timestamp, _ = strconv.ParseInt(o.GetString("timestamp"), 10, 64)
+	}
+	ps.Sort()
+	reqStr := ps.String()
+	str := "GET&" +
+		percentEncode("/") + "&" +
+		percentEncode(reqStr)
+	str = SP(str, "%3A", "%253A", -1)
+	log.Println("-11-:", str)
+	h := hmac.New(func() hash.Hash { return sha1.New() }, []byte(SECRET+"&"))
+	io.WriteString(h, str)
+	signedStr = base64.StdEncoding.EncodeToString(h.Sum(nil))
+	return
+}
 
-		log.Println(timestamp, "---", ttamp)
-		if (ttamp - timestamp) > LIMIT_TIME {
+var SP = strings.Replace
 
+func percentEncode(str string) string {
+	str = url.QueryEscape(str)
+	str = SP(SP(SP(str, "+", "%20", -1), "*", "%2A", -1), "%7E", "~", -1)
+	return str
+}
+
+type paramSorter struct {
+	Keys []string
+	Vals []string
+}
+
+func (ps *paramSorter) String() string {
+	str := ""
+	for n, k := range ps.Keys {
+		str += k + "=" + ps.Vals[n]
+		if n < len(ps.Keys)-1 {
+			str += "&"
 		}
-		res, _ := mongodb.FindOneByField("user", &map[string]interface{}{
-			"appid":  appid,
-			"secret": secret,
-		}, nil)
-		if len(*res) > 0 {
-			//log.Println("res;", *res)
+	}
+	return str
+}
+func (ps *paramSorter) Query() string {
+	str := ""
+	for n, k := range ps.Keys {
+		str += k + "=" + url.QueryEscape(ps.Vals[n])
+		if n < len(ps.Keys)-1 {
+			str += "&"
 		}
 	}
-	log.Println("----")
-	o.ServeJson(map[string]interface{}{
-		"rData": rData,
-	})
+	return str
+}
+
+func (ps *paramSorter) Sort() {
+	sort.Sort(ps)
+}
+func (ps *paramSorter) Len() int {
+	return len(ps.Vals)
+}
+
+func (ps *paramSorter) Less(i, j int) bool {
+	return bytes.Compare([]byte(ps.Keys[i]), []byte(ps.Keys[j])) < 0
+}
+func (ps *paramSorter) Swap(i, j int) {
+	ps.Vals[i], ps.Vals[j] = ps.Vals[j], ps.Vals[i]
+	ps.Keys[i], ps.Keys[j] = ps.Keys[j], ps.Keys[i]
 }

+ 11 - 4
src/main.go

@@ -2,8 +2,8 @@ package main
 
 import (
 	. "apiservice/config"
-	_ "apiservice/oamanager"
-	"log"
+	. "apiservice/oamanager"
+	"net/http"
 	"qfw/util"
 	"qfw/util/elastic"
 	"qfw/util/redis"
@@ -18,9 +18,12 @@ func init() {
 }
 
 func main() {
-	log.Println(Sysconfig["webport"].(string))
+	//xweb.Run(":" + Sysconfig["webport"].(string))
 	go func() {
-		xweb.Run(":" + Sysconfig["webport"].(string))
+		//
+		mux1 := http.NewServeMux()
+		mux1.HandleFunc("/open", OpenAction)
+		xweb.RunBase(":"+Sysconfig["webport"].(string), mux1)
 	}()
 	b := make(chan bool, 1)
 	<-b
@@ -29,5 +32,9 @@ func main() {
 func initXweb() {
 	xweb.RootApp().AppConfig.TemplateDir = "web/templates"
 	xweb.RootApp().AppConfig.StaticDir = "web/staticres"
+	xweb.RootApp().AppConfig.StaticFileVersion = false
+	xweb.RootApp().AppConfig.CheckXsrf = false
+	xweb.RootApp().AppConfig.EnableHttpCache = false
 	xweb.RootApp().AppConfig.ReloadTemplates = true
+	xweb.RootApp().AppConfig.CacheTemplates = false
 }

BIN
src/src.exe


File diff suppressed because it is too large
+ 1 - 0
src/web/staticres/js/jquery-3.2.1.min.js


+ 40 - 1
src/web/templates/pc/article.html

@@ -1 +1,40 @@
-11111111111
+<html>
+
+<head>
+<title>扫码登录 - 剑鱼招标订阅</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1" />
+<meta name="Keywords" content="{{.T.obj.keywords}}"/>
+<meta name="Description" content="{{.T.obj.description}}"/>
+<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,initial-scale=1.0" user-scalable="no" />
+<meta name="renderer" content="webkit">
+<meta content="telephone=no" name="format-detection"/>
+<script src="/js/jquery-3.2.1.min.js"></script>
+</head>
+<body style="position: relative;">
+<div id="div" style="position: absolute; width: 60px;height: 30px;border-radius: 4px;left: 30%;top: 10%; border:1px solid #ccc; line-height: 30px;cursor: pointer;   text-align: center;    font-size: 14px;    padding: 5px 10px;">
+提交
+</div>
+<script type="text/javascript">
+$(function(){
+	console.log("---")
+	$("#div").click(function(){
+		$.ajax({
+		type: "POST",
+		url: "/open",
+		data:{	appid:"jyoaACJUW1BJXwECCA1fDwUj",
+				pagenum:1,
+				keyword:"拓普网络",
+				timestamp:1519719472,
+				action:"getdata",
+				signature:"kSqioYVr4YKLgqeRx/czLCzUUoI=",
+			},
+		dataType: "json",
+		success: function(r){
+			console.log(r)
+		}
+	});
+	})
+})
+</script>
+</body>
+</html>

Some files were not shown because too many files changed in this diff