// 认证成功后创建 token 和 session func authSuccess(ctx *gin.Context, authType string, user *model.User) { sid, err := session.NewSessionId() if err != nil { glog.Errorln(err) ctx.JSON(200, errors.ErrInternalServerError) return } timestamp := time.Now().Unix() tk := token.Token{ SessionId: sid, TokenId: token.NewTokenId(), AuthType: authType, ExpirationAccess: token.ExpirationAccess(timestamp), ExpirationRefresh: token.ExpirationRefresh(timestamp), } tkEncodedBytes, err := tk.Encode() if err != nil { glog.Errorln(err) ctx.JSON(200, errors.ErrTokenEncodeFailed) return } ss := session.Session{ TokenSignature: tk.Signatrue, UserId: user.Id, PasswordTag: user.PasswordTag, } if err = session.Add(sid, &ss); err != nil { glog.Errorln(err) ctx.JSON(200, errors.ErrInternalServerError) return } resp := struct { *errors.Error Token string `json:"token"` }{ Error: errors.ErrOK, Token: string(tkEncodedBytes), } ctx.JSON(200, &resp) return }
// 微信 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), } ctx.JSON(200, &resp) return } }