- refactor weixin and mini program login

This commit is contained in:
gazebo
2019-01-26 16:02:01 +08:00
parent ab53a4b61d
commit aba16383fe
10 changed files with 284 additions and 116 deletions

View File

@@ -12,10 +12,8 @@ import (
"git.rosy.net.cn/jx-callback/business/jxcallback/auth/mobile"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/model/legacymodel"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
"github.com/astaxie/beego/orm"
)
const (
@@ -31,7 +29,6 @@ const (
)
var (
ErrLoginFailed = errors.New("登录失败")
StrStateIsWrong = "state:%s状态不对"
)
@@ -40,6 +37,10 @@ var (
AutherMini *AutherMiniProgram
)
var (
ErrExceptionalLogin = errors.New("登录异常,无前置微信授权操作")
)
type Auther struct {
}
@@ -48,7 +49,8 @@ type AutherMiniProgram struct {
type UserInfoExt struct {
weixinapi.SNSUserInfo
TempPassword string `json:"tempPassword"` // 一段时间有效的登录密码
TempPassword string `json:"tempPassword"` // 一段时间有效的登录密码
LoginInfo *auth.LoginInfo `json:"loginInfo"`
}
func init() {
@@ -59,21 +61,41 @@ func init() {
auth.RegisterAuther(LoginTypeMiniProgram, AutherMini)
}
func GetUserInfo(code string, state string) (token *UserInfoExt, err error) {
globals.SugarLogger.Debugf("GetUserInfo code:%s", code)
func cacheSNSInfo(wxUserinfo *weixinapi.SNSUserInfo, password string, duration time.Duration) {
api.Cacher.Set(wxUserinfo.OpenID, password, duration)
api.Cacher.Set(wxUserinfo.OpenID+".sns", wxUserinfo, duration)
}
func getSNSInfoFromCache(openID string) (wxUserinfo *weixinapi.SNSUserInfo, password string) {
password, _ = api.Cacher.Get(wxUserinfo.OpenID).(string)
wxUserinfo = new(weixinapi.SNSUserInfo)
if err := api.Cacher.GetAs(wxUserinfo.OpenID+".sns", wxUserinfo); err != nil {
wxUserinfo = nil
}
return wxUserinfo, password
}
func GetWeiXinUserInfo(code string, state string) (userInfo *UserInfoExt, err error) {
globals.SugarLogger.Debugf("GetUserInfo code:%s", code)
if state == "" {
token, err2 := api.WeixinAPI.SNSGetToken(code)
if err = err2; err == nil {
wxUserinfo, err2 := api.WeixinAPI.SNSGetUserInfo(token.AccessToken, token.OpenID)
if err = err2; err == nil {
pwd := utils.GetUUID()
globals.SugarLogger.Debugf("GetUserInfo code:%s, pwd:%s", code, pwd)
api.Cacher.Set(wxUserinfo.OpenID, pwd, DefTempPasswordDuration)
return &UserInfoExt{
userInfo = &UserInfoExt{
SNSUserInfo: *wxUserinfo,
TempPassword: pwd,
}, nil
TempPassword: utils.GetUUID(),
}
globals.SugarLogger.Debugf("GetUserInfo code:%s, pwd:%s", code, userInfo.TempPassword)
// api.Cacher.Set(wxUserinfo.OpenID, userInfo.TempPassword, DefTempPasswordDuration)
cacheSNSInfo(wxUserinfo, userInfo.TempPassword, DefTempPasswordDuration)
user, err2 := dao.GetWeiXinUserByIDs(dao.GetDB(), "", wxUserinfo.UnionID, wxUserinfo.OpenID, "")
if err = err2; err == nil {
userInfo.LoginInfo = auth.CreateLoginInfo(user.Tel, mobile.LoginType)
} else if !dao.IsNoRowsError(err) { // 非用户不存在错误,报错
return nil, err
}
return userInfo, nil
}
}
} else {
@@ -82,23 +104,15 @@ func GetUserInfo(code string, state string) (token *UserInfoExt, err error) {
return nil, err
}
func (a *Auther) Login(openid, password string) (userID string, err error) {
// 此函数需要调整
func (a *Auther) Login(openid, password string) (userID, LoginType string, err error) {
globals.SugarLogger.Debugf("weixinsns Login openid:%s, password:%s", openid, password)
if value := api.Cacher.Get(openid); value != nil {
if password == value.(string) {
// wxUser := &legacymodel.WeiXins{
// OpenID: openid,
// }
// if err = dao.GetEntity(nil, wxUser, "OpenID"); err == nil {
api.Cacher.Del(openid)
return "", nil
// }
}
} else {
err = ErrLoginFailed
_, cachedPwd := getSNSInfoFromCache(openid)
if cachedPwd != "" && password == cachedPwd {
api.Cacher.Del(openid)
return "", "", nil
}
return "", err
return "", "", ErrExceptionalLogin
}
func (a *Auther) Logout(loginInfo *auth.LoginInfo) error {
@@ -106,39 +120,51 @@ func (a *Auther) Logout(loginInfo *auth.LoginInfo) error {
}
func BindMobile(token, mobileNum, code, nickname string) (err error) {
globals.SugarLogger.Debugf("BindMobile mobileNum:%s, code:%s, nickname:%s", mobileNum, code, nickname)
globals.SugarLogger.Debugf("BindMobile token:%s, mobileNum:%s, code:%s, nickname:%s", token, mobileNum, code, nickname)
loginInfo := new(auth.LoginInfo)
if err = api.Cacher.GetAs(token, loginInfo); err == nil {
if mobile.VerifyCode(mobileNum, code) {
user := &legacymodel.WeiXins{
OpenID: loginInfo.ID,
Tel: mobileNum,
NickName: nickname,
ParentID: -1,
if err = mobile.VerifyCode(mobileNum, code); err == nil {
wxUserinfo, _ := getSNSInfoFromCache(loginInfo.ID)
if wxUserinfo == nil {
return fmt.Errorf("绑定超时,请重新绑定")
}
db := dao.GetDB()
if err = dao.GetEntity(db, user, "OpenID"); err == nil {
user.Tel = mobileNum
user.NickName = nickname
_, err = dao.UpdateEntity(db, user, "Tel", "NickName")
} else if err == orm.ErrNoRows {
if err = dao.GetEntity(db, user, "Tel"); err == nil {
user.OpenID = loginInfo.ID
user.NickName = nickname
_, err = dao.UpdateEntity(db, user, "OpenID", "NickName")
}
if nickname == "" {
nickname = wxUserinfo.NickName
}
if err == orm.ErrNoRows {
err = dao.CreateEntity(db, user)
}
} else {
err = errors.New("验证码错")
err = auth.ConvertErr2NoUser(dao.UpdateWeiXinUser(dao.GetDB(), mobileNum, nickname, wxUserinfo.UnionID, wxUserinfo.OpenID, ""), mobileNum)
}
}
return err
}
// 绑定手机加登录
func BindMobile2(openid, secret, mobileNum, verifyCode, nickname string) (loginInfo *auth.LoginInfo, err error) {
globals.SugarLogger.Debugf("BindMobileEx openid:%s, secret:%s, mobileNum:%s, verifyCode:%s, nickname:%s", openid, secret, mobileNum, verifyCode, nickname)
err = ErrExceptionalLogin
if value := api.Cacher.Get(openid); value != nil {
wxUserinfo, cachedSecret := getSNSInfoFromCache(openid)
if wxUserinfo == nil {
return nil, fmt.Errorf("绑定超时,请重新绑定")
}
if secret == cachedSecret {
api.Cacher.Del(openid)
if err = mobile.VerifyCode(mobileNum, verifyCode); err == nil {
if nickname == "" {
nickname = wxUserinfo.NickName
}
if err = dao.UpdateWeiXinUser(dao.GetDB(), mobileNum, nickname, wxUserinfo.UnionID, wxUserinfo.OpenID, ""); err == nil {
loginInfo = auth.CreateLoginInfo(mobileNum, mobile.LoginType)
} else {
err = auth.ConvertErr2NoUser(err, mobileNum)
}
}
}
}
return loginInfo, err
}
// 对于小程序来说,
// 1用户必须先在后台创建手机号标识
// 2用户必须先绑定微信
@@ -155,46 +181,51 @@ func (a *AutherMiniProgram) BindWeiXin(ctx *jxcontext.Context, code, nickName st
if loginInfo == nil || loginInfo.LoginType != mobile.LoginType {
return fmt.Errorf("调用AutherMiniProgram BindWeiXin时必须以手机验证方式登录")
}
user := &legacymodel.WeiXins{
Tel: loginInfo.ID,
}
db := dao.GetDB()
if err = dao.GetEntity(db, user, "Tel"); err != nil {
return auth.ConvertErr2NoUser(err, loginInfo.ID)
}
sessionInfo, err := api.WeixinMiniAPI.SNSCode2Session(code)
if err != nil {
return err
}
user.OpenIDMini = sessionInfo.OpenID
cols := []string{"OpenIDMini"}
if nickName != "" {
user.NickName = nickName
cols = append(cols, "NickName")
}
_, err = dao.UpdateEntity(db, user, cols...)
return err
err = dao.UpdateWeiXinUser(dao.GetDB(), loginInfo.ID, nickName, sessionInfo.UnionID, "", sessionInfo.OpenID)
return auth.ConvertErr2NoUser(err, "")
}
func (a *AutherMiniProgram) Login(mobileNum, code string) (userID string, err error) {
// 绑定手机加登录
// func (a *AutherMiniProgram) BindMobile2(code, nickName, mobileNum, verifyCode string) (loginInfo *auth.LoginInfo, err error) {
// globals.SugarLogger.Debugf("BindMobile2 code:%s, nickName:%s, mobileNum:%s, verifyCode:%s", code, nickName, mobileNum, verifyCode)
// err = ErrExceptionalLogin
// if mobile.VerifyCode(mobileNum, code) {
// sessionInfo, err := api.WeixinMiniAPI.SNSCode2Session(code)
// if err != nil {
// return nil, err
// }
// if err = dao.UpdateWeiXinUser(dao.GetDB(), mobileNum, nickName, sessionInfo.UnionID, "", sessionInfo.OpenID); err == nil {
// api.Cacher.Set(composeSessionKeyCacheKey(sessionInfo.OpenID), sessionInfo.SessionKey, auth.DefTokenDuration)
// loginInfo = auth.CreateLoginInfo(mobileNum, mobile.LoginType)
// }
// } else {
// err = ErrVerifyCodeIsWrong
// }
// return loginInfo, err
// }
func (a *AutherMiniProgram) Login(mobileNum, code string) (userID, LoginType string, err error) {
globals.SugarLogger.Debugf("AutherMiniProgram Login mobileNum:%s, code:%s", mobileNum, code)
sessionInfo, err := api.WeixinMiniAPI.SNSCode2Session(code)
if err != nil {
return "", err
}
user := &legacymodel.WeiXins{
OpenIDMini: sessionInfo.OpenID,
return "", "", err
}
db := dao.GetDB()
if err = dao.GetEntity(db, user, "OpenIDMini"); err != nil {
return "", auth.ConvertErr2NoUser(err, mobileNum)
user, err := dao.GetWeiXinUserByIDs(db, "", sessionInfo.UnionID, "", sessionInfo.OpenID)
if err != nil {
return "", "", auth.ConvertErr2NoUser(err, mobileNum)
}
globals.SugarLogger.Debugf("AutherMiniProgram Login user.Tel:%s, code:%s, openID:%s", user.Tel, code, sessionInfo.OpenID)
if mobileNum != user.Tel {
}
api.Cacher.Set(composeSessionKeyCacheKey(sessionInfo.OpenID), sessionInfo.SessionKey, auth.DefTokenDuration)
return sessionInfo.OpenID, err
api.Cacher.Set(composeSessionKeyCacheKey(user.Tel), sessionInfo.SessionKey, auth.DefTokenDuration)
err = auth.ConvertErr2NoUser(dao.UpdateWeiXinUser(db, user.Tel, "", sessionInfo.UnionID, "", sessionInfo.OpenID), mobileNum)
return user.Tel, mobile.LoginType, err
}
func (a *AutherMiniProgram) Logout(loginInfo *auth.LoginInfo) error {