Parcourir la source

change jwt-token

zjxpcyc il y a 6 ans
Parent
révision
fe9a6a2b32
7 fichiers modifiés avec 466 ajouts et 228 suppressions
  1. 43
    168
      controllers/auth.go
  2. 0
    1
      controllers/context.go
  3. 7
    0
      models/constant.go
  4. 11
    24
      service/customer/customer.go
  5. 302
    35
      service/sys.go
  6. 47
    0
      utils/jwt.go
  7. 56
    0
      utils/wechat.go

+ 43
- 168
controllers/auth.go Voir le fichier

@@ -6,200 +6,75 @@ import (
6 6
 	"spaceofcheng/services/models/model"
7 7
 	"spaceofcheng/services/service"
8 8
 	"spaceofcheng/services/utils"
9
-	"strings"
10
-
11
-	"github.com/astaxie/beego"
9
+	"time"
12 10
 )
13 11
 
14 12
 // Authenticate 权限验证
15 13
 func (c *BaseController) authenticate() {
16
-
17
-	// 默认 service
18 14
 	serv := service.NewSysServ(c.Context)
19 15
 
20
-	orgID := c.GetString(":org")
21
-	if orgID == "" {
22
-		c.ResponseError(errors.New("接口地址访问不正确"))
23
-	}
24
-	serv.SetOrgByID(orgID)
25
-
26
-	// 客户端类型
27
-	clientType := utils.GetClientType(c.Ctx.Request)
28
-
29
-	switch clientType {
30
-	case utils.ClientAdmin:
31
-		c.authPCAdmin(serv)
32
-	case utils.ClientWechat:
33
-		c.authWechat(serv)
34
-	default:
35
-		c.ResponseError(
36
-			errors.New("暂不支持的 API 场景"),
37
-			http.StatusBadRequest,
38
-		)
39
-	}
40
-}
16
+	// 鉴权 - 并初始化上下文
17
+	res := serv.AuthAndInitCtx(c.Ctx)
41 18
 
42
-// authPCAdmin PC管理端
43
-func (c *BaseController) authPCAdmin(serv *service.SysServ) {
44
-	if !c.needAuth() {
45
-		return
46
-	}
19
+	// 设置 TOKEN
20
+	c.setToken()
47 21
 
48
-	// 用户ID
49
-	userID := ""
50
-	userIDRaw := c.GetSession(SNUserID)
51
-	if userIDRaw != nil {
52
-		userID = userIDRaw.(string)
53
-	}
22
+	if res != nil {
23
+		code := http.StatusOK
24
+		if res["code"] != nil {
25
+			code = res["code"].(int)
26
+		}
54 27
 
55
-	if userID == "" {
56
-		c.ResponseError(
57
-			errors.New("用户未登录"),
58
-			http.StatusUnauthorized,
59
-		)
60
-	}
28
+		if code != http.StatusOK {
29
+			err := res["error"].(error)
30
+			data := map[string]interface{}{}
61 31
 
62
-	if err := serv.SetUserProfile(userID); err != nil {
63
-		// utils.LogError(err.Error())
32
+			if res["message"] != nil {
33
+				data = res["message"].(map[string]interface{})
34
+			}
64 35
 
65
-		c.ResponseError(
66
-			utils.LogError(err.Error()),
67
-			http.StatusInternalServerError,
68
-		)
36
+			c.ResponseData(data, err, code)
37
+		}
69 38
 	}
70
-
71
-	// 设置 Session
72
-	c.SetSession(SNUserID, userID)
73 39
 }
74 40
 
75
-// authWechat 微信端
76
-func (c *BaseController) authWechat(serv *service.SysServ) {
77
-	custID := ""
78
-	custIDRaw := c.GetSession(SNCustID)
79
-	if custIDRaw != nil {
80
-		custID = custIDRaw.(string)
81
-	}
82
-
83
-	// 机构
84
-	org := c.Context.Get("org").(model.SysOrg)
85
-
86
-	// 微信配置
87
-	wxConf, err := serv.GetWeChatConfig(org.OrgId)
88
-	if err != nil {
89
-		utils.LogError("查询微信配置失败: " + err.Error())
90
-		c.ResponseError(
91
-			errors.New("没有找到微信相关配置"),
92
-			http.StatusBadRequest,
93
-		)
94
-	}
95
-	utils.WxClientSingleton(org.OrgId, wxConf)
41
+// setToken 设置 TOKEN
42
+// 15 分钟后过期
43
+func (c *BaseController) setToken() {
44
+	var token *utils.JWTToken
45
+	exp := time.Now().Local().Add(15 * time.Second)
96 46
 
97
-	// 用户微信信息
98
-	var wxDetail map[string]interface{}
47
+	if c.Context.Get("user") != nil {
48
+		user := c.Context.Get("user").(model.SysUser)
99 49
 
100
-	detailRaw := c.GetSession("wechat_user")
101
-	if detailRaw != nil {
102
-		wxDetail = detailRaw.(map[string]interface{})
103
-	} else {
104
-		// DEV MODE
105
-		if c.RunMode == "dev" {
106
-			wxDetail = map[string]interface{}{
107
-				"openid":     "OPENID",
108
-				"nickname":   "NICKNAME",
109
-				"sex":        "1",
110
-				"province":   "PROVINCE",
111
-				"city":       "CITY",
112
-				"country":    "COUNTRY",
113
-				"headimgurl": "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
114
-				"unionid":    "o6_bmasdasdsad6_2sgVt7hMZOPfL",
115
-			}
116
-		} else {
117
-			wxDetail = c.getWechatDetail(org.OrgId, serv)
50
+		token = &utils.JWTToken{
51
+			Guest:  false,
52
+			ID:     user.UserId,
53
+			Expire: exp,
118 54
 		}
55
+	} else if c.Context.Get("userMap") != nil {
56
+		userMap := c.Context.Get("userMap").(model.TaUserMapping)
119 57
 
120
-		c.SetSession("wechat_user", wxDetail)
121
-	}
122
-
123
-	c.Context.Set("wxInfo", wxDetail)
124
-
125
-	// 用户映射检查
126
-	userMap, err := serv.CheckWechatUserMapping(wxDetail)
127
-	if err != nil {
128
-		c.ResponseError(
129
-			utils.LogError("获取人员映射账户失败: "+err.Error()),
130
-			http.StatusInternalServerError,
131
-		)
132
-	}
133
-	c.Context.Set("userMap", *userMap)
134
-
135
-	if !c.needAuth() {
136
-		return
137
-	}
138
-	// 未登录或者绑定, 返回 406
139
-	if custID == "" && userMap.UserId == "" {
140
-		// 新增用户信息
141
-		cust, err := serv.SaveNewCustomer(wxDetail, userMap)
142
-		if err != nil {
143
-			c.ResponseError(err)
58
+		token = &utils.JWTToken{
59
+			Guest:  false,
60
+			ID:     userMap.Openid,
61
+			Expire: exp,
144 62
 		}
145
-		custID = cust.CustomerId
146
-		// c.ResponseError(
147
-		// 	errors.New("用户未登录或绑定"),
148
-		// 	http.StatusNotAcceptable,
149
-		// )
150
-	}
151
-
152
-	if custID == "" {
153
-		custID = userMap.UserId
154
-	}
155
-	if custID != "" {
156
-		if err := serv.SetCustomer(custID); err != nil {
157
-			utils.LogError(err.Error())
158
-
159
-			c.ResponseError(
160
-				errors.New("内部错误, 请重试"),
161
-				http.StatusInternalServerError,
162
-			)
63
+	} else {
64
+		token = &utils.JWTToken{
65
+			Guest:  true,
66
+			Expire: exp,
163 67
 		}
164
-
165
-		// 设置 Session
166
-		c.SetSession(SNCustID, custID)
167
-	}
168
-}
169
-
170
-func (c *BaseController) needAuth() bool {
171
-	route := c.Ctx.Input.URL()
172
-	apiPrefix := beego.AppConfig.String("api::prefix")
173
-	guestAPI := beego.AppConfig.String("api::guest")
174
-
175
-	if strings.Index(route, apiPrefix+strings.Split(guestAPI, ":")[0]) > -1 {
176
-		return false
177
-	}
178
-
179
-	return true
180
-}
181
-
182
-// getWechatDetail 获取微信个人信息详情
183
-func (c *BaseController) getWechatDetail(org string, serv *service.SysServ) map[string]interface{} {
184
-	// 微信 code
185
-	code := c.GetString("code")
186
-	if code == "" {
187
-		c.ResponseData(
188
-			map[string]interface{}{
189
-				"appid": utils.GetWxAppID(org),
190
-			},
191
-			errors.New("获取微信信息失败"),
192
-			http.StatusUnauthorized,
193
-		)
194 68
 	}
195 69
 
196
-	usr, err := utils.WxClientFor(org).GetUserInfo(code)
70
+	tokenEncode, err := utils.CreateToken(token.ToMap())
197 71
 	if err != nil {
72
+		utils.LogError("系统生成 Token 失败: " + err.Error())
198 73
 		c.ResponseError(
199
-			utils.LogError("获取微信个人信息失败: "+err.Error()),
74
+			errors.New("系统异常, 请退出重试"),
200 75
 			http.StatusInternalServerError,
201 76
 		)
202 77
 	}
203 78
 
204
-	return usr
79
+	c.Ctx.Output.Header(utils.TokenHeader, utils.TokenSchema+" "+tokenEncode)
205 80
 }

+ 0
- 1
controllers/context.go Voir le fichier

@@ -12,7 +12,6 @@ import (
12 12
 * user					SysUser 									用户基本信息
13 13
 * customer			TaCustomer 								会员基本信息
14 14
 * userMap				TaUserMapping 						用户/会员 映射第三方账户
15
-* wxInfo				map[string]interface{} 		微信信息
16 15
 * cases					[]SysUserCase 						用户所有案场信息
17 16
 * currentCase		SysUserCase 							当前案场
18 17
 * org						SysOrg 										用户当前组织

+ 7
- 0
models/constant.go Voir le fichier

@@ -117,6 +117,13 @@ const (
117 117
 	GIVE_GIFT_GYM            = "gym"
118 118
 )
119 119
 
120
+// 卡券发放类型
121
+const (
122
+	GIVE_TYPE_SYSTEM  = "system"
123
+	GIVE_TYPE_CASE    = "case"
124
+	GIVE_TYPE_CHANNEL = "channel"
125
+)
126
+
120 127
 // 游泳健身卡种类
121 128
 const (
122 129
 	GYM_CARD_ONCE    = "once"

+ 11
- 24
service/customer/customer.go Voir le fichier

@@ -1,6 +1,7 @@
1 1
 package customer
2 2
 
3 3
 import (
4
+	"encoding/json"
4 5
 	"errors"
5 6
 	"spaceofcheng/services/models"
6 7
 	"spaceofcheng/services/models/cases"
@@ -104,15 +105,14 @@ func (s *CustomerServ) BindWechatUser(userMap *model.TaUserMapping, phone string
104 105
 	}
105 106
 
106 107
 	if cust == nil {
107
-		wxInfoRaw := s.ctx.Get("wxInfo")
108
-		if wxInfoRaw == nil {
109
-			return nil, errors.New("请确定使用微信端登录")
108
+		wxInfo := utils.WechatUser{}
109
+		if err := json.Unmarshal([]byte(userMap.AccountInfo), &wxInfo); err != nil {
110
+			utils.LogError("解析用户微信映射信息失败: " + err.Error())
111
+			return nil, errors.New("系统数据异常")
110 112
 		}
111 113
 
112
-		wxInfo := wxInfoRaw.(map[string]interface{})
113 114
 		// 更新用户手机号码信息及userid信息
114
-		openid := wxInfo["openid"].(string)
115
-		customer, err := s.dao.GetCustWithWXByOpenID(openid)
115
+		customer, err := s.dao.GetCustWithWXByOpenID(wxInfo.OpenID)
116 116
 
117 117
 		newCust := model.TaCustomer{
118 118
 			CustomerId: customer.CustomerId,
@@ -128,11 +128,6 @@ func (s *CustomerServ) BindWechatUser(userMap *model.TaUserMapping, phone string
128 128
 			return nil, err
129 129
 		}
130 130
 
131
-		// newCust, err := s.SaveNewCustomer(wxInfo, "", "", user.Phone, user.UserId)
132
-		// if err != nil {
133
-		// 	utils.LogError(err.Error())
134
-		// 	return nil, err
135
-		// }
136 131
 		cust = &newCust
137 132
 	} else {
138 133
 		if cust.Status != models.STATUS_NORMAL {
@@ -168,16 +163,14 @@ func (s *CustomerServ) BindWechatCust(userMap *model.TaUserMapping, phone, caseI
168 163
 
169 164
 	// 用户不存在, 则新增
170 165
 	if cust == nil {
171
-		wxInfoRaw := s.ctx.Get("wxInfo")
172
-		if wxInfoRaw == nil {
173
-			return nil, errors.New("请确定使用微信端登录")
166
+		wxInfo := utils.WechatUser{}
167
+		if err := json.Unmarshal([]byte(userMap.AccountInfo), &wxInfo); err != nil {
168
+			utils.LogError("解析用户微信映射信息失败: " + err.Error())
169
+			return nil, errors.New("系统数据异常")
174 170
 		}
175 171
 
176
-		wxInfo := wxInfoRaw.(map[string]interface{})
177
-
178 172
 		// 更新用户手机号码信息及userid信息
179
-		openid := wxInfo["openid"].(string)
180
-		customer, err := s.dao.GetCustWithWXByOpenID(openid)
173
+		customer, err := s.dao.GetCustWithWXByOpenID(wxInfo.OpenID)
181 174
 		newCust := model.TaCustomer{
182 175
 			CustomerId:  customer.CustomerId,
183 176
 			Phone:       phone,
@@ -228,12 +221,6 @@ func (s *CustomerServ) BindWechatCust(userMap *model.TaUserMapping, phone, caseI
228 221
 			return nil, err
229 222
 		}
230 223
 
231
-		// newCust, err := s.SaveNewCustomer(wxInfo, caseID, userID, phone, "")
232
-		// if err != nil {
233
-		// 	utils.LogError(err.Error())
234
-		// 	return nil, err
235
-		// }
236
-
237 224
 		cust = &newCust
238 225
 	} else {
239 226
 		if cust.Status != models.STATUS_NORMAL {

+ 302
- 35
service/sys.go Voir le fichier

@@ -3,12 +3,15 @@ package service
3 3
 import (
4 4
 	"encoding/json"
5 5
 	"errors"
6
+	"net/http"
6 7
 	"spaceofcheng/services/models"
7 8
 	"spaceofcheng/services/models/customer"
8 9
 	"spaceofcheng/services/models/model"
9 10
 	"spaceofcheng/services/utils"
11
+	"strings"
10 12
 
11 13
 	"github.com/astaxie/beego"
14
+	"github.com/astaxie/beego/context"
12 15
 )
13 16
 
14 17
 const (
@@ -17,6 +20,7 @@ const (
17 20
 
18 21
 // SysServ 系统处理
19 22
 type SysServ struct {
23
+	org         model.SysOrg
20 24
 	ctx         *utils.Context
21 25
 	dao         *models.SysDAO
22 26
 	customerdao *customer.CustomerDAO
@@ -31,6 +35,284 @@ func NewSysServ(ctx *utils.Context) *SysServ {
31 35
 	}
32 36
 }
33 37
 
38
+// AuthAndInitCtx 鉴权
39
+// gctx 是 beego 框架中的 Context
40
+func (s *SysServ) AuthAndInitCtx(gctx *context.Context) map[string]interface{} {
41
+	// 确认机构
42
+	orgID := gctx.Input.Query(":org")
43
+	if orgID == "" {
44
+		return map[string]interface{}{
45
+			"code":  http.StatusBadRequest,
46
+			"error": errors.New("接口地址访问不正确"),
47
+		}
48
+	}
49
+	if err := s.SetOrgByID(orgID); err != nil {
50
+		return map[string]interface{}{
51
+			"code":  http.StatusInternalServerError,
52
+			"error": err,
53
+		}
54
+	}
55
+
56
+	// 获取 token
57
+	token, err := s.getToken(gctx)
58
+	if err != nil {
59
+		return map[string]interface{}{
60
+			"code":  http.StatusInternalServerError,
61
+			"error": err,
62
+		}
63
+	}
64
+	if token != nil {
65
+		s.ctx.Set("token", *token)
66
+	}
67
+
68
+	// 客户端类型
69
+	// 通过 UA 判断
70
+	clientType := utils.GetClientType(gctx.Request)
71
+
72
+	// pc 管理端
73
+	if clientType == utils.ClientAdmin {
74
+		return s.authPCAdmin(gctx)
75
+	}
76
+
77
+	// wechat 端
78
+	if clientType == utils.ClientWechat {
79
+		return s.authWechat(gctx)
80
+	}
81
+
82
+	return map[string]interface{}{
83
+		"code":  http.StatusBadRequest,
84
+		"error": errors.New("暂无该客户端的 API"),
85
+	}
86
+}
87
+
88
+// authPCAdmin
89
+// 管理端 API 校验
90
+func (s *SysServ) authPCAdmin(gctx *context.Context) map[string]interface{} {
91
+	if !s.needAuth(gctx) {
92
+		return nil
93
+	}
94
+
95
+	token := utils.JWTToken{}
96
+	if s.ctx.Get("token") != nil {
97
+		token = s.ctx.Get("token").(utils.JWTToken)
98
+	}
99
+
100
+	if token.ID == "" || token.Guest == true {
101
+		return map[string]interface{}{
102
+			"code":  http.StatusUnauthorized,
103
+			"error": errors.New("用户未登录"),
104
+		}
105
+	}
106
+
107
+	if err := s.SetUserProfile(token.ID); err != nil {
108
+		return map[string]interface{}{
109
+			"code":  http.StatusInternalServerError,
110
+			"error": err,
111
+		}
112
+	}
113
+
114
+	return nil
115
+}
116
+
117
+func (s *SysServ) authWechat(gctx *context.Context) map[string]interface{} {
118
+	// 微信 code
119
+	code := gctx.Input.Query("code")
120
+
121
+	token := utils.JWTToken{}
122
+	if s.ctx.Get("token") != nil {
123
+		token = s.ctx.Get("token").(utils.JWTToken)
124
+	}
125
+
126
+	var wxUser *utils.WechatUser
127
+	var openID string
128
+
129
+	// 未登录 或 未验证
130
+	if token.ID == "" {
131
+		// 需要微信验证
132
+		if code == "" {
133
+			return map[string]interface{}{
134
+				"code":  http.StatusUnauthorized,
135
+				"error": errors.New("请授权微信用户登录"),
136
+				"message": map[string]interface{}{
137
+					"appid": utils.GetWxAppID(s.org.OrgId),
138
+				},
139
+			}
140
+		}
141
+
142
+		// 微信用户信息
143
+		var err error
144
+		wxUser, err = s.wechartSignIn(gctx, code)
145
+		if err != nil {
146
+			return map[string]interface{}{
147
+				"code":  http.StatusInternalServerError,
148
+				"error": err,
149
+			}
150
+		}
151
+
152
+		if wxUser == nil {
153
+			return map[string]interface{}{
154
+				"code":  http.StatusInternalServerError,
155
+				"error": errors.New("请先关注公众号"),
156
+			}
157
+		}
158
+
159
+		openID = wxUser.OpenID
160
+	} else {
161
+		openID = token.ID
162
+	}
163
+
164
+	// 查询数据库是否存在已有映射
165
+	userMapList, err := s.dao.GetUserMappingByOpenID(openID)
166
+	if err != nil {
167
+		utils.LogError("校验人员失败: " + err.Error())
168
+		return map[string]interface{}{
169
+			"code":  http.StatusInternalServerError,
170
+			"error": errors.New("校验人员失败"),
171
+		}
172
+	}
173
+
174
+	var userMapping *model.TaUserMapping
175
+	for _, ump := range userMapList {
176
+		if openID == ump.Openid && models.ACCMAP_WECHAT == ump.AccountType {
177
+			userMapping = &ump
178
+		}
179
+	}
180
+
181
+	// 如果尚无人员映射信息, 代表人员初次使用本系统
182
+	if userMapping == nil {
183
+		// 如果没有微信用户信息, 代表产生了未知异常
184
+		if wxUser == nil || wxUser.UnionID == "" {
185
+			return map[string]interface{}{
186
+				"code":  http.StatusInternalServerError,
187
+				"error": errors.New("系统异常, 请清空缓存后重试"),
188
+			}
189
+		}
190
+
191
+		wxInfoJSON, err := json.Marshal(wxUser)
192
+		if err != nil {
193
+			utils.LogError("转换微信json信息失败: " + err.Error())
194
+			return map[string]interface{}{
195
+				"code":  http.StatusInternalServerError,
196
+				"error": errors.New("微信信息异常"),
197
+			}
198
+		}
199
+
200
+		userMapping = &model.TaUserMapping{
201
+			AccountType: models.ACCMAP_WECHAT,
202
+			Openid:      openID,
203
+			Uuid:        wxUser.UnionID,
204
+			AccountInfo: string(wxInfoJSON),
205
+		}
206
+	}
207
+
208
+	// 更新映射信息, 没有的话则插入
209
+	err = s.dao.UpdateUserMapping(userMapping)
210
+	if err != nil {
211
+		utils.LogError("保存用户映射信息失败: " + err.Error())
212
+		return map[string]interface{}{
213
+			"code":  http.StatusInternalServerError,
214
+			"error": errors.New("更新用户信息失败"),
215
+		}
216
+	}
217
+	s.ctx.Set("userMap", *userMapping)
218
+
219
+	if !s.needAuth(gctx) {
220
+		return nil
221
+	}
222
+
223
+	var cust *model.TaCustomer
224
+
225
+	// 如果只有映射, 但是没有人员信息
226
+	// 则新增人员
227
+	if userMapping.UserId == "" {
228
+		cust, err = s.saveNewCustomer(wxUser, userMapping)
229
+		if err != nil {
230
+			return map[string]interface{}{
231
+				"code":  http.StatusInternalServerError,
232
+				"error": err,
233
+			}
234
+		}
235
+	} else {
236
+		cust, err = s.customerdao.GetCustomerByID(userMapping.UserId)
237
+		if err != nil {
238
+			utils.LogError("查询用户信息失败: " + err.Error())
239
+			return map[string]interface{}{
240
+				"code":  http.StatusInternalServerError,
241
+				"error": err,
242
+			}
243
+		}
244
+	}
245
+	s.ctx.Set("customer", *cust)
246
+
247
+	if cust.UserId != "" {
248
+		if err := s.SetUserProfile(cust.UserId); err != nil {
249
+			return map[string]interface{}{
250
+				"code":  http.StatusInternalServerError,
251
+				"error": err,
252
+			}
253
+		}
254
+	}
255
+
256
+	return nil
257
+}
258
+
259
+// wechartSignIn 使用 code 微信登录
260
+func (s *SysServ) wechartSignIn(gctx *context.Context, code string) (*utils.WechatUser, error) {
261
+	if beego.BConfig.RunMode == "dev" {
262
+		return &utils.WechatUser{
263
+			OpenID: "OPENID",
264
+		}, nil
265
+	}
266
+
267
+	// 初始化微信配置
268
+	if err := s.initWechatClient(s.org.OrgId); err != nil {
269
+		utils.LogError("初始化微信客户端失败: " + err.Error())
270
+		return nil, errors.New("初始化微信客户端失败")
271
+	}
272
+
273
+	// 获取 微信信息
274
+	// 可能出现的情况是 openid 获取到了, 但是详情没有获取到
275
+	wxUserMap, err := utils.WxClientFor(s.org.OrgId).GetUserInfo(code)
276
+	if err != nil {
277
+		utils.LogError("获取微信信息失败: " + err.Error())
278
+
279
+		if wxUserMap == nil {
280
+			return nil, errors.New("获取微信信息失败")
281
+		}
282
+	}
283
+
284
+	return utils.MapToWechatUser(wxUserMap), nil
285
+}
286
+
287
+func (s *SysServ) getToken(gctx *context.Context) (*utils.JWTToken, error) {
288
+	tokenRaw := gctx.Input.Header(utils.TokenHeader)
289
+	if tokenRaw == "" {
290
+		return nil, nil
291
+	}
292
+
293
+	tokenEnStr := strings.Trim(strings.TrimLeft(tokenRaw, utils.TokenSchema), " ")
294
+
295
+	token, err := utils.PareseToken(tokenEnStr)
296
+	if err != nil {
297
+		utils.LogError("解析 Token 失败: " + err.Error())
298
+		return nil, errors.New("解析 Token 失败")
299
+	}
300
+
301
+	return utils.MapToJWTToken(token), nil
302
+}
303
+
304
+func (s *SysServ) needAuth(gctx *context.Context) bool {
305
+	route := gctx.Input.URL()
306
+	apiPrefix := beego.AppConfig.String("api::prefix")
307
+	guestAPI := beego.AppConfig.String("api::guest")
308
+
309
+	if strings.Index(route, apiPrefix+strings.Split(guestAPI, ":")[0]) > -1 {
310
+		return false
311
+	}
312
+
313
+	return true
314
+}
315
+
34 316
 // SetUserProfile 设置用户信息
35 317
 func (s *SysServ) SetUserProfile(id string) error {
36 318
 	user, err := s.dao.GetPureUserInfo(id)
@@ -60,32 +342,14 @@ func (s *SysServ) SetUserProfile(id string) error {
60 342
 	return nil
61 343
 }
62 344
 
63
-// SetCustomer 设置客户信息
64
-func (s *SysServ) SetCustomer(id string) error {
65
-	cust, err := s.dao.GetCustomer(id)
66
-	if err != nil {
67
-		return utils.LogError("获取客户基本信息失败: " + err.Error())
68
-	}
69
-
70
-	s.ctx.Set("customer", *cust)
71
-	return nil
72
-}
73
-
74
-// SaveNewCustomer 新增用户
75
-func (s *SysServ) SaveNewCustomer(wxInfo map[string]interface{}, userMap *model.TaUserMapping) (*model.TaCustomer, error) {
76
-	// 微信相关字段
77
-	nickyName := wxInfo["nickname"].(string)
78
-	sex := wxInfo["sex"].(float64)
79
-	headimgurl := wxInfo["headimgurl"].(string)
80
-
81
-	org := s.ctx.Get("org").(model.SysOrg)
82
-
345
+// saveNewCustomer 新增用户
346
+func (s *SysServ) saveNewCustomer(wxUser *utils.WechatUser, userMap *model.TaUserMapping) (*model.TaCustomer, error) {
83 347
 	cust := model.TaCustomer{
84
-		CustomerName: nickyName,
85
-		Name:         nickyName,
86
-		Sex:          int(sex),
87
-		Headimgurl:   headimgurl,
88
-		OrgId:        org.OrgId,
348
+		CustomerName: wxUser.NickName,
349
+		Name:         wxUser.NickName,
350
+		Sex:          int(wxUser.Sex),
351
+		Headimgurl:   wxUser.HeadImgURL,
352
+		OrgId:        s.org.OrgId,
89 353
 	}
90 354
 
91 355
 	if err := s.customerdao.SaveCustomer(&cust); err != nil {
@@ -130,7 +394,6 @@ func (s *SysServ) CheckWechatUserMapping(user map[string]interface{}) (*model.Ta
130 394
 
131 395
 	accountRaw, err := json.Marshal(user)
132 396
 	if err != nil {
133
-		beego.Error(err)
134 397
 		return nil, err
135 398
 	}
136 399
 	account := string(accountRaw)
@@ -146,7 +409,6 @@ func (s *SysServ) CheckWechatUserMapping(user map[string]interface{}) (*model.Ta
146 409
 	userMapList, err := s.dao.GetUserMappingByOpenID(openID)
147 410
 
148 411
 	if err != nil {
149
-		beego.Error(err)
150 412
 		return nil, err
151 413
 	}
152 414
 
@@ -172,24 +434,28 @@ func (s *SysServ) CheckWechatUserMapping(user map[string]interface{}) (*model.Ta
172 434
 	return &userMapping, nil
173 435
 }
174 436
 
175
-// GetWeChatConfig 获取微信配置
176
-func (s SysServ) GetWeChatConfig(org string) (map[string]string, error) {
177
-	conf, err := s.dao.GetWeChatConfig(org)
437
+// initWechatClient 初始化微信客户端
438
+func (s SysServ) initWechatClient(orgID string) error {
439
+	conf, err := s.dao.GetWeChatConfig(orgID)
178 440
 	if err != nil {
179
-		return nil, err
441
+		utils.LogError("获取微信配置失败: " + err.Error())
442
+		return errors.New("获取微信配置失败")
180 443
 	}
181 444
 
182
-	if conf.ConfId == "" {
183
-		return nil, errors.New("未找到微信配置")
445
+	if conf == nil || conf.ConfId == "" {
446
+		return errors.New("未找到微信配置")
184 447
 	}
185 448
 
186
-	return map[string]string{
449
+	cert := map[string]string{
187 450
 		"appid":  conf.Appid,
188 451
 		"secret": conf.Secret,
189 452
 		"token":  conf.Token,
190 453
 		"aeskey": conf.Aeskey,
191 454
 		"wxid":   conf.Wxid,
192
-	}, nil
455
+	}
456
+
457
+	utils.WxClientSingleton(orgID, cert)
458
+	return nil
193 459
 }
194 460
 
195 461
 // SetOrgByID 获取组织
@@ -203,6 +469,7 @@ func (s SysServ) SetOrgByID(orgID string) error {
203 469
 	}
204 470
 
205 471
 	s.ctx.Set("org", *org)
472
+	s.org = *org
206 473
 
207 474
 	return nil
208 475
 }

+ 47
- 0
utils/jwt.go Voir le fichier

@@ -2,10 +2,16 @@ package utils
2 2
 
3 3
 import (
4 4
 	"errors"
5
+	"time"
5 6
 
6 7
 	jwt "github.com/dgrijalva/jwt-go"
7 8
 )
8 9
 
10
+const (
11
+	TokenHeader = "Authorization"
12
+	TokenSchema = "Bearer"
13
+)
14
+
9 15
 var tokenSignedKey = []byte(`Yansen is so handsome!`)
10 16
 
11 17
 // CreateToken 获取token
@@ -32,3 +38,44 @@ func PareseToken(token string) (map[string]interface{}, error) {
32 38
 
33 39
 	return nil, errors.New("Token 解析 未知错误")
34 40
 }
41
+
42
+// JWTToken token 内容
43
+type JWTToken struct {
44
+	Guest    bool
45
+	ID       string
46
+	Password string
47
+	Expire   time.Time
48
+}
49
+
50
+// ToMap 转 map
51
+func (t *JWTToken) ToMap() map[string]interface{} {
52
+	return map[string]interface{}{
53
+		"guest":    t.Guest,
54
+		"user":     t.ID,
55
+		"password": t.Password,
56
+		"exp":      t.Expire,
57
+	}
58
+}
59
+
60
+// MapToJWTToken map 映射 Token
61
+func MapToJWTToken(data map[string]interface{}) *JWTToken {
62
+	token := JWTToken{}
63
+
64
+	if data["guest"] != nil {
65
+		token.Guest = data["guest"].(bool)
66
+	}
67
+
68
+	if data["user"] != nil {
69
+		token.ID = data["user"].(string)
70
+	}
71
+
72
+	if data["password"] != nil {
73
+		token.Password = data["password"].(string)
74
+	}
75
+
76
+	if data["exp"] != nil {
77
+		token.Expire = data["exp"].(time.Time)
78
+	}
79
+
80
+	return &token
81
+}

+ 56
- 0
utils/wechat.go Voir le fichier

@@ -6,6 +6,17 @@ import (
6 6
 
7 7
 var wxClients map[string]*wx.Client
8 8
 
9
+type WechatUser struct {
10
+	OpenID     string  `json:"openid"`
11
+	NickName   string  `json:"nickname"`
12
+	Sex        float64 `json:"sex"`
13
+	Province   string  `json:"province"`
14
+	City       string  `json:"city"`
15
+	Country    string  `json:"country"`
16
+	HeadImgURL string  `json:"headimgurl"`
17
+	UnionID    string  `json:"unionid"`
18
+}
19
+
9 20
 // WxClientSingleton 初始化
10 21
 func WxClientSingleton(org string, cert map[string]string) {
11 22
 	if wxClients == nil {
@@ -32,3 +43,48 @@ func GetWxAppID(org string) string {
32 43
 func init() {
33 44
 	wx.SetLogInst(defaultLogger)
34 45
 }
46
+
47
+// MapToWechatUser 映射微信人员
48
+func MapToWechatUser(data map[string]interface{}) *WechatUser {
49
+	subscribe, has := data["subscribe"]
50
+	if has {
51
+		if subscribe == nil {
52
+			return nil
53
+		}
54
+
55
+		sub := subscribe.(float64)
56
+		if sub == 0 {
57
+			return nil
58
+		}
59
+	}
60
+
61
+	user := WechatUser{
62
+		OpenID: data["openid"].(string),
63
+	}
64
+
65
+	if data["sex"] != nil {
66
+		user.Sex = data["sex"].(float64)
67
+	}
68
+
69
+	if data["province"] != nil {
70
+		user.Province = data["province"].(string)
71
+	}
72
+
73
+	if data["city"] != nil {
74
+		user.City = data["city"].(string)
75
+	}
76
+
77
+	if data["country"] != nil {
78
+		user.Country = data["country"].(string)
79
+	}
80
+
81
+	if data["headimgurl"] != nil {
82
+		user.HeadImgURL = data["headimgurl"].(string)
83
+	}
84
+
85
+	if data["unionid"] != nil {
86
+		user.UnionID = data["unionid"].(string)
87
+	}
88
+
89
+	return &user
90
+}