|
@@ -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 := ¶mSorter{[]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]
|
|
|
}
|