本文整理汇总了Golang中github.com/chanxuehong/util/security.SecureCompareString函数的典型用法代码示例。如果您正苦于以下问题:Golang SecureCompareString函数的具体用法?Golang SecureCompareString怎么用?Golang SecureCompareString使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了SecureCompareString函数的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: ServeHTTP
func ServeHTTP(w http.ResponseWriter, r *http.Request, queryValues url.Values, srv Server, errHandler ErrorHandler) {
switch r.Method {
case "POST":
RawMsgXML, err := ioutil.ReadAll(r.Body)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
msg, err := util.DecodeXMLToMap(bytes.NewReader(RawMsgXML))
if err != nil {
errHandler.ServeError(w, r, err)
return
}
ReturnCode, ok := msg["return_code"]
if ReturnCode == ReturnCodeSuccess || !ok {
haveAppId := msg["appid"]
wantAppId := srv.AppId()
if wantAppId != "" && !security.SecureCompareString(haveAppId, wantAppId) {
err = fmt.Errorf("the message's appid mismatch, have: %s, want: %s", haveAppId, wantAppId)
errHandler.ServeError(w, r, err)
return
}
haveMchId := msg["mch_id"]
wantMchId := srv.MchId()
if wantMchId != "" && !security.SecureCompareString(haveMchId, wantMchId) {
err = fmt.Errorf("the message's mch_id mismatch, have: %s, want: %s", haveMchId, wantMchId)
errHandler.ServeError(w, r, err)
return
}
// 认证签名
signature1, ok := msg["sign"]
if !ok {
err = errors.New("no sign parameter")
errHandler.ServeError(w, r, err)
return
}
signature2 := Sign(msg, srv.APIKey(), nil)
if !security.SecureCompareString(signature1, signature2) {
err = fmt.Errorf("check signature failed, \r\ninput: %q, \r\nlocal: %q", signature1, signature2)
errHandler.ServeError(w, r, err)
return
}
}
req := &Request{
HttpRequest: r,
RawMsgXML: RawMsgXML,
Msg: msg,
}
srv.MessageHandler().ServeMessage(w, req)
default:
errHandler.ServeError(w, r, errors.New("Not expect Request.Method: "+r.Method))
}
}
开发者ID:jsix,项目名称:wechat,代码行数:60,代码来源:serve_http.go
示例2: ServeHTTP
// ServeHTTP 处理 http 消息请求
// NOTE: 调用者保证所有参数有效
func ServeHTTP(w http.ResponseWriter, r *http.Request, queryValues url.Values, srv AgentServer, errHandler ErrorHandler) {
LogInfoln("[WECHAT_DEBUG] request uri:", r.RequestURI)
LogInfoln("[WECHAT_DEBUG] request remote-addr:", r.RemoteAddr)
LogInfoln("[WECHAT_DEBUG] request user-agent:", r.UserAgent())
switch r.Method {
case "POST": // 消息处理
msgSignature1 := queryValues.Get("msg_signature")
if msgSignature1 == "" {
errHandler.ServeError(w, r, errors.New("msg_signature is empty"))
return
}
timestampStr := queryValues.Get("timestamp")
if timestampStr == "" {
errHandler.ServeError(w, r, errors.New("timestamp is empty"))
return
}
timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
if err != nil {
err = errors.New("can not parse timestamp to int64: " + timestampStr)
errHandler.ServeError(w, r, err)
return
}
nonce := queryValues.Get("nonce")
if nonce == "" {
errHandler.ServeError(w, r, errors.New("nonce is empty"))
return
}
reqBody, err := ioutil.ReadAll(r.Body)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
LogInfoln("[WECHAT_DEBUG] request msg http body:\r\n", string(reqBody))
// 解析 RequestHttpBody
var requestHttpBody RequestHttpBody
if err := xml.Unmarshal(reqBody, &requestHttpBody); err != nil {
errHandler.ServeError(w, r, err)
return
}
haveCorpId := requestHttpBody.CorpId
wantCorpId := srv.CorpId()
if wantCorpId != "" && !security.SecureCompareString(haveCorpId, wantCorpId) {
err = fmt.Errorf("the RequestHttpBody's ToUserName mismatch, have: %s, want: %s", haveCorpId, wantCorpId)
errHandler.ServeError(w, r, err)
return
}
haveAgentId := requestHttpBody.AgentId
wantAgentId := srv.AgentId()
if wantCorpId != "" && wantAgentId != -1 {
if haveAgentId != wantAgentId && haveAgentId != 0 {
err = fmt.Errorf("the RequestHttpBody's AgentId mismatch, have: %d, want: %d", haveAgentId, wantAgentId)
errHandler.ServeError(w, r, err)
return
}
// 此时
// 要么 haveAgentId == wantAgentId,
// 要么 haveAgentId == 0
}
agentToken := srv.Token()
// 验证签名
msgSignature2 := util.MsgSign(agentToken, timestampStr, nonce, requestHttpBody.EncryptedMsg)
if !security.SecureCompareString(msgSignature1, msgSignature2) {
err := fmt.Errorf("check msg_signature failed, input: %s, local: %s", msgSignature1, msgSignature2)
errHandler.ServeError(w, r, err)
return
}
// 解密
encryptedMsgBytes, err := base64.StdEncoding.DecodeString(requestHttpBody.EncryptedMsg)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
aesKey := srv.CurrentAESKey()
random, rawMsgXML, aesAppId, err := util.AESDecryptMsg(encryptedMsgBytes, aesKey)
if err != nil {
// 尝试用上一次的 AESKey 来解密
lastAESKey, isLastAESKeyValid := srv.LastAESKey()
if !isLastAESKeyValid {
errHandler.ServeError(w, r, err)
return
}
aesKey = lastAESKey // NOTE
random, rawMsgXML, aesAppId, err = util.AESDecryptMsg(encryptedMsgBytes, aesKey)
if err != nil {
//.........这里部分代码省略.........
开发者ID:Wang,项目名称:wechat,代码行数:101,代码来源:serve_http.debug.go
示例3: ServeHTTP
// ServeHTTP 处理 http 消息请求
// NOTE: 调用者保证所有参数有效
func ServeHTTP(w http.ResponseWriter, r *http.Request, queryValues url.Values, srv Server, errHandler mp.ErrorHandler) {
switch r.Method {
case "POST": // 消息处理
switch encryptType := queryValues.Get("encrypt_type"); encryptType {
case "aes":
msgSignature1 := queryValues.Get("msg_signature")
if msgSignature1 == "" {
errHandler.ServeError(w, r, errors.New("msg_signature is empty"))
return
}
timestampStr := queryValues.Get("timestamp")
if timestampStr == "" {
errHandler.ServeError(w, r, errors.New("timestamp is empty"))
return
}
timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
if err != nil {
err = errors.New("can not parse timestamp to int64: " + timestampStr)
errHandler.ServeError(w, r, err)
return
}
nonce := queryValues.Get("nonce")
if nonce == "" {
errHandler.ServeError(w, r, errors.New("nonce is empty"))
return
}
var requestHttpBody RequestHttpBody
if err := xml.NewDecoder(r.Body).Decode(&requestHttpBody); err != nil {
errHandler.ServeError(w, r, err)
return
}
haveAppId := requestHttpBody.AppId
wantAppId := srv.AppId()
if wantAppId != "" && !security.SecureCompareString(haveAppId, wantAppId) {
err = fmt.Errorf("the RequestHttpBody's AppId mismatch, have: %s, want: %s", haveAppId, wantAppId)
errHandler.ServeError(w, r, err)
return
}
token := srv.Token()
// 验证签名
msgSignature2 := util.MsgSign(token, timestampStr, nonce, requestHttpBody.EncryptedMsg)
if !security.SecureCompareString(msgSignature1, msgSignature2) {
err = fmt.Errorf("check msg_signature failed, input: %s, local: %s", msgSignature1, msgSignature2)
errHandler.ServeError(w, r, err)
return
}
// 解密
encryptedMsgBytes, err := base64.StdEncoding.DecodeString(requestHttpBody.EncryptedMsg)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
aesKey := srv.CurrentAESKey()
random, rawMsgXML, aesAppId, err := util.AESDecryptMsg(encryptedMsgBytes, aesKey)
if err != nil {
// 尝试用上一次的 AESKey 来解密
lastAESKey, isLastAESKeyValid := srv.LastAESKey()
if !isLastAESKeyValid {
errHandler.ServeError(w, r, err)
return
}
aesKey = lastAESKey // NOTE
random, rawMsgXML, aesAppId, err = util.AESDecryptMsg(encryptedMsgBytes, aesKey)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
}
if haveAppId != string(aesAppId) {
err = fmt.Errorf("the RequestHttpBody's ToUserName(==%s) mismatch the AppId with aes encrypt(==%s)", haveAppId, aesAppId)
errHandler.ServeError(w, r, err)
return
}
// 解密成功, 解析 MixedMessage
var mixedMsg MixedMessage
if err := xml.Unmarshal(rawMsgXML, &mixedMsg); err != nil {
errHandler.ServeError(w, r, err)
return
}
// 安全考虑再次验证 AppId
if haveAppId != mixedMsg.AppId {
err = fmt.Errorf("the RequestHttpBody's AppId(==%s) mismatch the MixedMessage's AppId(==%s)", haveAppId, mixedMsg.AppId)
errHandler.ServeError(w, r, err)
return
}
//.........这里部分代码省略.........
开发者ID:jsix,项目名称:wechat,代码行数:101,代码来源:serve_http.go
示例4: MustAuthAndNotGuestHandler
// 检查客户端是否是认证状态, 并且不是 guest 认证.
// 如果是, 添加 sso_token_string<-->x-token, sso_token<-->*token.Token, sso_session<-->*session.Session, sso_user<-->*model.User 到 ctx *gin.Context;
// 如果否, 终止 Handlers Chain.
func MustAuthAndNotGuestHandler(ctx *gin.Context) {
tkString := ctx.Request.Header.Get("x-token")
if tkString == "" {
ctx.JSON(200, errors.ErrTokenMissing)
ctx.Abort()
return
}
// 解析 token 并判断 AuthType 是否正确, 是否过期
tk := &token.Token{}
if err := tk.Decode([]byte(tkString)); err != nil {
glog.Errorln(err)
ctx.JSON(200, errors.ErrTokenDecodeFailed)
ctx.Abort()
return
}
if tk.AuthType == token.AuthTypeGuest {
ctx.JSON(200, errors.ErrTokenShouldNotGuest)
ctx.Abort()
return
}
if time.Now().Unix() >= tk.ExpirationAccess {
ctx.JSON(200, errors.ErrTokenAccessExpired)
ctx.Abort()
return
}
// 获取 Session 并判断与 token 是否匹配
ss, err := session.Get(tk.SessionId)
if err != nil {
glog.Errorln(err)
if err == errors.ErrNotFound {
ctx.JSON(200, errors.ErrTokenInvalid)
ctx.Abort()
return
}
ctx.JSON(200, errors.ErrInternalServerError)
ctx.Abort()
return
}
if !security.SecureCompareString(tk.Signatrue, ss.TokenSignature) {
ctx.JSON(200, errors.ErrTokenInvalid)
ctx.Abort()
return
}
// 获取用户信息并判断与 token, session 是否一致
user, err := model.Get(ss.UserId)
if err != nil {
glog.Errorln(err)
if err == model.ErrNotFound {
ctx.JSON(200, errors.ErrTokenInvalid)
ctx.Abort()
return
}
ctx.JSON(200, errors.ErrInternalServerError)
ctx.Abort()
return
}
bindType, err := token.GetBindType(tk.AuthType)
if err != nil {
glog.Errorln(err)
ctx.JSON(200, errors.ErrTokenInvalid)
ctx.Abort()
return
}
if user.BindTypes&bindType == 0 {
ctx.JSON(200, errors.ErrTokenInvalid)
ctx.Abort()
return
}
if tk.AuthType == token.AuthTypeEmailPassword || tk.AuthType == token.AuthTypePhonePassword {
if ss.PasswordTag != user.PasswordTag {
ctx.JSON(200, errors.ErrTokenInvalid)
ctx.Abort()
return
}
}
ctx.Set("sso_token_string", tkString)
ctx.Set("sso_token", tk)
ctx.Set("sso_session", ss)
ctx.Set("sso_user", user)
}
开发者ID:bmbstack,项目名称:go-user,代码行数:87,代码来源:must_auth_and_not_guest.go
示例5: RefreshHandler
// 刷新 token
func RefreshHandler(ctx *gin.Context) {
tkString := ctx.Request.Header.Get("x-token")
if tkString == "" {
ctx.JSON(200, errors.ErrTokenMissing)
return
}
// 解析 token
tk := &token.Token{}
if err := tk.Decode([]byte(tkString)); err != nil {
glog.Errorln(err)
ctx.JSON(200, errors.ErrTokenDecodeFailed)
return
}
// 如果是 guest 直接返回
if tk.AuthType == token.AuthTypeGuest {
resp := struct {
*errors.Error
Token string `json:"token"`
}{
Error: errors.ErrOK,
Token: tkString,
}
ctx.JSON(200, &resp)
return
}
timestamp := time.Now().Unix()
if timestamp >= tk.ExpirationRefresh {
ctx.JSON(200, errors.ErrTokenRefreshExpired)
return
}
if timestamp+1200 < tk.ExpirationAccess { // 过早的刷新也是直接返回
resp := struct {
*errors.Error
Token string `json:"token"`
}{
Error: errors.ErrOK,
Token: tkString,
}
ctx.JSON(200, &resp)
return
}
if tk.ExpirationAccess >= tk.ExpirationRefresh { // 提前 1200秒 暴力的结束, 防止客户端循环的刷新
ctx.JSON(200, errors.ErrTokenRefreshExpired)
return
}
// 现在我们真的需要刷新token啦!!!
// 获取 Session 并判断与 token 是否匹配
ss, err := session.Get(tk.SessionId)
if err != nil {
glog.Errorln(err)
if err == errors.ErrNotFound {
ctx.JSON(200, errors.ErrTokenInvalid)
return
}
ctx.JSON(200, errors.ErrInternalServerError)
return
}
if !security.SecureCompareString(tk.Signatrue, ss.TokenSignature) {
ctx.JSON(200, errors.ErrTokenInvalid)
return
}
// 获取用户信息并判断与 token, session 是否一致
user, err := model.Get(ss.UserId)
if err != nil {
glog.Errorln(err)
if err == model.ErrNotFound {
ctx.JSON(200, errors.ErrTokenInvalid)
return
}
ctx.JSON(200, errors.ErrInternalServerError)
return
}
bindType, err := token.GetBindType(tk.AuthType)
if err != nil {
glog.Errorln(err)
ctx.JSON(200, errors.ErrTokenInvalid)
return
}
if user.BindTypes&bindType == 0 {
ctx.JSON(200, errors.ErrTokenInvalid)
return
}
if tk.AuthType == token.AuthTypeEmailPassword || tk.AuthType == token.AuthTypePhonePassword {
if ss.PasswordTag != user.PasswordTag {
ctx.JSON(200, errors.ErrTokenInvalid)
return
}
}
tk2 := token.Token{
SessionId: tk.SessionId,
TokenId: token.NewTokenId(),
AuthType: tk.AuthType,
//.........这里部分代码省略.........
开发者ID:bmbstack,项目名称:go-user,代码行数:101,代码来源:refresh.go
示例6: ServeHTTP
// ServeHTTP 处理 http 消息请求
// NOTE: 调用者保证所有参数有效
func ServeHTTP(w http.ResponseWriter, r *http.Request, queryValues url.Values, srv Server, errHandler ErrorHandler) {
LogInfoln("[WECHAT_DEBUG] request uri:", r.RequestURI)
LogInfoln("[WECHAT_DEBUG] request remote-addr:", r.RemoteAddr)
LogInfoln("[WECHAT_DEBUG] request user-agent:", r.UserAgent())
switch r.Method {
case "POST": // 消息处理
switch encryptType := queryValues.Get("encrypt_type"); encryptType {
case "aes": // 安全模式, 兼容模式
signature := queryValues.Get("signature") // 只读取, 不做校验
msgSignature1 := queryValues.Get("msg_signature")
if msgSignature1 == "" {
errHandler.ServeError(w, r, errors.New("msg_signature is empty"))
return
}
timestampStr := queryValues.Get("timestamp")
if timestampStr == "" {
errHandler.ServeError(w, r, errors.New("timestamp is empty"))
return
}
timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
if err != nil {
err = errors.New("can not parse timestamp to int64: " + timestampStr)
errHandler.ServeError(w, r, err)
return
}
nonce := queryValues.Get("nonce")
if nonce == "" {
errHandler.ServeError(w, r, errors.New("nonce is empty"))
return
}
reqBody, err := ioutil.ReadAll(r.Body)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
LogInfoln("[WECHAT_DEBUG] request msg http body:\r\n", string(reqBody))
var requestHttpBody RequestHttpBody
if err := xml.Unmarshal(reqBody, &requestHttpBody); err != nil {
errHandler.ServeError(w, r, err)
return
}
// 安全考虑验证下 ToUserName
haveToUserName := requestHttpBody.ToUserName
wantToUserName := srv.OriId()
if wantToUserName != "" && !security.SecureCompareString(haveToUserName, wantToUserName) {
err := fmt.Errorf("the RequestHttpBody's ToUserName mismatch, have: %s, want: %s", haveToUserName, wantToUserName)
errHandler.ServeError(w, r, err)
return
}
token := srv.Token()
// 验证签名
msgSignature2 := util.MsgSign(token, timestampStr, nonce, requestHttpBody.EncryptedMsg)
if !security.SecureCompareString(msgSignature1, msgSignature2) {
err := fmt.Errorf("check msg_signature failed, input: %s, local: %s", msgSignature1, msgSignature2)
errHandler.ServeError(w, r, err)
return
}
// 解密
encryptedMsgBytes, err := base64.StdEncoding.DecodeString(requestHttpBody.EncryptedMsg)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
aesKey := srv.CurrentAESKey()
random, rawMsgXML, haveAppIdBytes, err := util.AESDecryptMsg(encryptedMsgBytes, aesKey)
if err != nil {
// 尝试用上一次的 AESKey 来解密
lastAESKey, isLastAESKeyValid := srv.LastAESKey()
if !isLastAESKeyValid {
errHandler.ServeError(w, r, err)
return
}
aesKey = lastAESKey // NOTE
random, rawMsgXML, haveAppIdBytes, err = util.AESDecryptMsg(encryptedMsgBytes, aesKey)
if err != nil {
errHandler.ServeError(w, r, err)
return
}
}
haveAppId := string(haveAppIdBytes)
wantAppId := srv.AppId()
if wantAppId != "" && !security.SecureCompareString(haveAppId, wantAppId) {
err := fmt.Errorf("the message's appid mismatch, have: %s, want: %s", haveAppId, wantAppId)
errHandler.ServeError(w, r, err)
//.........这里部分代码省略.........
开发者ID:jsix,项目名称:wechat,代码行数:101,代码来源:serve_http.debug.go
示例7: AuthHandler
// 微信 oauth2 认证
// 需要提供 code, state 参数.
func AuthHandler(ctx *gin.Context) {
// MustAuthHandler(ctx)
queryValues := ctx.Request.URL.Query()
code := queryValues.Get("code")
if code == "" {
ctx.JSON(200, errors.ErrBadRequest)
return
}
state := queryValues.Get("state")
if state == "" {
ctx.JSON(200, errors.ErrBadRequest)
return
}
ss := ctx.MustGet("sso_session").(*session.Session)
// 比较 state 是否一致
if !security.SecureCompareString(state, ss.OAuth2State) {
ctx.JSON(200, errors.ErrOAuthStateMismatch)
return
}
oauth2Client := oauth2.Client{
Config: oauth2Config,
}
oauth2Token, err := oauth2Client.Exchange(code)
if err != nil {
glog.Errorln(err)
ctx.JSON(200, errors.ErrInternalServerError)
return
}
if oauth2Token.UnionId == "" {
glog.Errorln("unionid is empty")
ctx.JSON(200, errors.ErrInternalServerError)
return
}
timestamp := time.Now().Unix()
user, err := model.GetByWechat(oauth2Token.UnionId)
switch err {
default:
glog.Errorln(err)
ctx.JSON(200, errors.ErrInternalServerError)
return
case model.ErrNotFound:
var oauth2UserInfo openOAuth2.UserInfo
if err = oauth2Client.GetUserInfo(&oauth2UserInfo, ""); err != nil {
glog.Errorln(err)
ctx.JSON(200, errors.ErrInternalServerError)
return
}
user, err = model.AddByWechat(oauth2Token.UnionId, oauth2UserInfo.Nickname, timestamp)
if err != nil {
glog.Errorln(err)
ctx.JSON(200, errors.ErrInternalServerError)
return
}
fallthrough
case nil:
sid, err := session.NewSessionId()
if err != nil {
glog.Errorln(err)
ctx.JSON(200, errors.ErrInternalServerError)
return
}
tk2 := token.Token{
SessionId: sid,
TokenId: token.NewTokenId(),
AuthType: token.AuthTypeOAuthWechat,
ExpirationAccess: token.ExpirationAccess(timestamp),
ExpirationRefresh: token.ExpirationRefresh(timestamp),
}
tk2EncodedBytes, err := tk2.Encode()
if err != nil {
glog.Errorln(err)
ctx.JSON(200, errors.ErrTokenEncodeFailed)
return
}
ss2 := session.Session{
TokenSignature: tk2.Signatrue,
UserId: user.Id,
PasswordTag: user.PasswordTag,
}
if err = session.Add(sid, &ss2); err != nil {
glog.Errorln(err)
ctx.JSON(200, errors.ErrInternalServerError)
return
}
resp := struct {
*errors.Error
Token string `json:"token"`
}{
Error: errors.ErrOK,
Token: string(tk2EncodedBytes),
//.........这里部分代码省略.........
开发者ID:bmbstack,项目名称:go-user,代码行数:101,代码来源:auth.go
示例8: ServeHTTP
// ServeHTTP 处理微信服务器的回调请求, queryParams 参数可以为 nil.
func (srv *Server) ServeHTTP(w http.ResponseWriter, r *http.Request, queryParams url.Values) {
callback.DebugPrintRequest(r)
errorHandler := srv.errorHandler
switch r.Method {
case "POST":
requestBody, err := ioutil.ReadAll(r.Body)
if err != nil {
errorHandler.ServeError(w, r, err)
return
}
callback.DebugPrintRequestMessage(requestBody)
msg, err := util.DecodeXMLToMap(bytes.NewReader(requestBody))
if err != nil {
errorHandler.ServeError(w, r, err)
return
}
returnCode, ok := msg["return_code"]
if returnCode == ReturnCodeSuccess || !ok {
haveAppId := msg["appid"]
wantAppId := srv.appId
if haveAppId != "" && wantAppId != "" && !security.SecureCompareString(haveAppId, wantAppId) {
err = fmt.Errorf("appid mismatch, have: %s, want: %s", haveAppId, wantAppId)
errorHandler.ServeError(w, r, err)
return
}
haveMchId := msg["mch_id"]
wantMchId := srv.mchId
if haveMchId != "" && wantMchId != "" && !security.SecureCompareString(haveMchId, wantMchId) {
err = fmt.Errorf("mch_id mismatch, have: %s, want: %s", haveMchId, wantMchId)
errorHandler.ServeError(w, r, err)
return
}
// 认证签名
haveSignature, ok := msg["sign"]
if !ok {
err = ErrNotFoundSign
errorHandler.ServeError(w, r, err)
return
}
wantSignature := Sign(msg, srv.apiKey, nil)
if !security.SecureCompareString(haveSignature, wantSignature) {
err = fmt.Errorf("sign mismatch,\nhave: %s,\nwant: %s", haveSignature, wantSignature)
errorHandler.ServeError(w, r, err)
return
}
}
ctx := &Context{
Server: srv,
ResponseWriter: w,
Request: r,
RequestBody: requestBody,
Msg: msg,
handlerIndex: initHandlerIndex,
}
srv.handler.ServeMsg(ctx)
default:
errorHandler.ServeError(w, r, errors.New("Unexpected HTTP Method: "+r.Method))
}
}
开发者ID:btbxbob,项目名称:wechat,代码行数:69,代码来源:server.go
示例9: ServeHTTP
// ServeHTTP 处理微信服务器的回调请求, queryParams 参数可以为 nil.
func (srv *Server) ServeHTTP(w http.ResponseWriter, r *http.Request, queryParams url.Values) {
callback.DebugPrintRequest(r)
if queryParams == nil {
queryParams = r.URL.Query()
}
errorHandler := srv.errorHandler
switch r.Method {
case "POST": // 推送消息(事件)
switch encryptType := queryParams.Get("encrypt_type"); encryptType {
case "aes":
haveSignature := queryParams.Get("signature")
if haveSignature == "" {
errorHandler.ServeError(w, r, errors.New("not found signature query parameter"))
return
}
haveMsgSignature := queryParams.Get("msg_signature")
if haveMsgSignature == "" {
errorHandler.ServeError(w, r, errors.New("not found msg_signature query parameter"))
return
}
timestampString := queryParams.Get("timestamp")
if timestampString == "" {
errorHandler.ServeError(w, r, errors.New("not found timestamp query parameter"))
return
}
timestamp, err := strconv.ParseInt(timestampString, 10, 64)
if err != nil {
err = fmt.Errorf("can not parse timestamp query parameter %q to int64", timestampString)
errorHandler.ServeError(w, r, err)
return
}
nonce := queryParams.Get("nonce")
if nonce == "" {
errorHandler.ServeError(w, r, errors.New("not found nonce query parameter"))
return
}
var token string
currentToken, lastToken := srv.getToken()
if currentToken == "" {
err = errors.New("token was not set for Server, see NewServer function or Server.SetToken method")
errorHandler.ServeError(w, r, err)
return
}
token = currentToken
wantSignature := util.Sign(token, timestampString, nonce)
if !security.SecureCompareString(haveSignature, wantSignature) {
if lastToken == "" {
err = fmt.Errorf("check signature failed, have: %s, want: %s", haveSignature, wantSignature)
errorHandler.ServeError(w, r, err)
return
}
token = lastToken
wantSignature = util.Sign(token, timestampString, nonce)
if !security.SecureCompareString(haveSignature, wantSignature) {
err = fmt.Errorf("check signature failed, have: %s, want: %s", haveSignature, wantSignature)
errorHandler.ServeError(w, r, err)
return
}
} else {
if lastToken != "" {
srv.removeLastToken(lastToken)
}
}
requestBodyBuf := textBufferPool.Get().(*bytes.Buffer)
requestBodyBuf.Reset()
defer textBufferPool.Put(requestBodyBuf)
if _, err = requestBodyBuf.ReadFrom(r.Body); err != nil {
errorHandler.ServeError(w, r, err)
return
}
requestBodyBytes := requestBodyBuf.Bytes()
var requestHttpBody cipherRequestHttpBody
if err = xmlUnmarshal(requestBodyBytes, &requestHttpBody); err != nil {
errorHandler.ServeError(w, r, err)
return
}
haveToUserName := requestHttpBody.ToUserName
wantToUserName := srv.oriId
if wantToUserName != "" && !security.SecureCompareString(haveToUserName, wantToUserName) {
err = fmt.Errorf("the message ToUserName mismatch, have: %s, want: %s",
haveToUserName, wantToUserName)
errorHandler.ServeError(w, r, err)
return
}
wantMsgSignature := util.MsgSign(token, timestampString, nonce, string(requestHttpBody.Base64EncryptedMsg))
if !security.SecureCompareString(haveMsgSignature, wantMsgSignature) {
err = fmt.Errorf("check msg_signature failed, have: %s, want: %s", haveMsgSignature, wantMsgSignature)
errorHandler.ServeError(w, r, err)
return
}
encryptedMsg := make([]byte, base64.StdEncoding.DecodedLen(len(requestHttpBody.Base64EncryptedMsg)))
//.........这里部分代码省略.........
开发者ID:btbxbob,项目名称:wechat,代码行数:101,代码来源:server.go
注:本文中的github.com/chanxuehong/util/security.SecureCompareString函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论