/
utils_id.go
104 lines (94 loc) · 2.44 KB
/
utils_id.go
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package web
import (
"crypto/sha512"
"encoding/base64"
"net/http"
"strings"
)
func getRealIP(req *http.Request) string {
ts := []string{"X-Forwarded-For", "x-forwarded-for", "X-FORWARDED-FOR"}
for _, k := range ts {
if v := req.Header.Get(k); v != "" {
return v
}
}
return ""
}
func hashSha512(s string) string {
sum := sha512.Sum512([]byte(s))
return base64.StdEncoding.EncodeToString(sum[:])
}
func generateUserID(req *http.Request) string {
ip := getRealIP(req)
if ip == "" {
ip = strings.Split(req.RemoteAddr, ":")[0]
}
ip = strings.TrimSpace(strings.Replace(ip, ".", "", -1))
ua := req.UserAgent()
return ip + classifyUA(ua) + hashSha512(ip + ua)[:15]
}
func maskUserID(id string) string {
bts := []byte(id)
bts[2] = 'x' // mask IP addresses
bts[3] = 'x'
bts[4] = 'x'
bts[5] = 'x'
bts[6] = 'x'
bts[7] = 'x'
bts[8] = 'x'
bs := string(bts)
if len(bs) > 23 {
bs = bs[:23] + "..."
}
return bs
}
func classifyUA(ua string) string {
var (
us = ""
raw = strings.Replace(strings.ToLower(ua), " ", "", -1)
)
// OS
switch {
case strings.Contains(raw, "linux"):
us += "linux"
case strings.Contains(raw, "macintosh") || strings.Contains(raw, "macos"):
us += "mac"
case strings.Contains(raw, "windows"):
us += "window"
case strings.Contains(raw, "iphone"):
us += "iphone"
case strings.Contains(raw, "android"):
us += "android"
case len(raw) > 7:
us += raw[2:7]
default:
us += raw
}
// browser
switch {
case strings.Contains(raw, "firefox/") && !strings.Contains(raw, "seammonkey/"):
us += "firefox"
case strings.Contains(raw, ";msie"):
us += "ie"
case strings.Contains(raw, "safari/") && !strings.Contains(raw, "chrome/") && !strings.Contains(raw, "chromium/"):
us += "safari"
case strings.Contains(raw, "chrome/") || strings.Contains(raw, "chromium/"):
us += "chrome"
case len(raw) > 15:
us += raw[9:14]
}
return us
}