github.com/sereiner/library@v0.0.0-20200518095232-1fa3e640cc5f/security/xsrf/xsrf.go (about)

     1  package xsrf
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/hmac"
     6  	"crypto/sha1"
     7  	"encoding/base64"
     8  	"fmt"
     9  	"io/ioutil"
    10  	"strconv"
    11  	"strings"
    12  	"time"
    13  )
    14  
    15  //CreateXSRFToken 生成xsrf token
    16  func CreateXSRFToken(secret string, data string) string {
    17  	var buf bytes.Buffer
    18  	encoder := base64.NewEncoder(base64.StdEncoding, &buf)
    19  	encoder.Write([]byte(data))
    20  	encoder.Close()
    21  	vb := buf.Bytes()
    22  	timestamp := strconv.FormatInt(time.Now().Unix(), 10)
    23  	sig := getCookieSig(secret, vb, timestamp)
    24  	return strings.Join([]string{string(vb), timestamp, sig}, "|")
    25  }
    26  func getCookieSig(key string, val []byte, timestamp string) string {
    27  	hm := hmac.New(sha1.New, []byte(key))
    28  
    29  	hm.Write(val)
    30  	hm.Write([]byte(timestamp))
    31  
    32  	hex := fmt.Sprintf("%02x", hm.Sum(nil))
    33  	return hex
    34  }
    35  
    36  //ParseXSRFToken 转换xsrf token
    37  func ParseXSRFToken(secret string, value string) string {
    38  	parts := strings.SplitN(value, "|", 3)
    39  	val, timestamp, sig := parts[0], parts[1], parts[2]
    40  	if getCookieSig(secret, []byte(val), timestamp) != sig {
    41  		return ""
    42  	}
    43  
    44  	ts, _ := strconv.ParseInt(timestamp, 0, 64)
    45  	if time.Now().Unix()-31*86400 > ts {
    46  		return ""
    47  	}
    48  
    49  	buf := bytes.NewBufferString(val)
    50  	encoder := base64.NewDecoder(base64.StdEncoding, buf)
    51  
    52  	res, _ := ioutil.ReadAll(encoder)
    53  	return string(res)
    54  }