- refactor weixin and mini program login
This commit is contained in:
@@ -2,7 +2,6 @@ package auth
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
@@ -17,7 +16,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type IAuther interface {
|
type IAuther interface {
|
||||||
Login(id, secret string) (userID string, err error)
|
Login(id, secret string) (userID, loginType string, err error)
|
||||||
Logout(loginInfo *LoginInfo) error
|
Logout(loginInfo *LoginInfo) error
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,6 +25,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
ErrUserNotExist = errors.New("用户不存在,请联系运营创建")
|
||||||
ErrLoginTypeNotSupported = errors.New("不支持指定的登录类型")
|
ErrLoginTypeNotSupported = errors.New("不支持指定的登录类型")
|
||||||
ErrUIDAndPassNotMatch = errors.New("用户与密码不匹配")
|
ErrUIDAndPassNotMatch = errors.New("用户与密码不匹配")
|
||||||
)
|
)
|
||||||
@@ -45,25 +45,34 @@ func RegisterAuther(loginType string, handler IAuther) {
|
|||||||
authers[loginType] = handler
|
authers[loginType] = handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreateLoginInfo(id, loginType string) (loginInfo *LoginInfo) {
|
||||||
|
token := utils.GetUUID()
|
||||||
|
loginInfo = &LoginInfo{
|
||||||
|
ID: id,
|
||||||
|
LoginType: loginType,
|
||||||
|
ExpiresIn: time.Now().Add(DefTokenDuration).Unix(),
|
||||||
|
Token: token,
|
||||||
|
}
|
||||||
|
globals.SugarLogger.Debugf("CreateLoginInfo id:%s, loginType:%s, loginInfo:%s", id, loginType, utils.Format4Output(loginInfo, true))
|
||||||
|
api.Cacher.Set(token, loginInfo, DefTokenDuration)
|
||||||
|
return loginInfo
|
||||||
|
}
|
||||||
|
|
||||||
func Login(id, loginType, secret string) (loginInfo *LoginInfo, err error) {
|
func Login(id, loginType, secret string) (loginInfo *LoginInfo, err error) {
|
||||||
globals.SugarLogger.Debugf("Login id:%s, loginType:%s, secret:%s", id, loginType, secret)
|
globals.SugarLogger.Debugf("Login id:%s, loginType:%s, secret:%s", id, loginType, secret)
|
||||||
if handler := authers[loginType]; handler != nil {
|
if handler := authers[loginType]; handler != nil {
|
||||||
userID, err2 := handler.Login(id, secret)
|
userID, loginType2, err2 := handler.Login(id, secret)
|
||||||
if err = err2; err == nil {
|
if err = err2; err == nil {
|
||||||
if userID != "" {
|
if userID != "" {
|
||||||
|
globals.SugarLogger.Debugf("Login id:%s, loginType:%s, id changed to:%s", id, loginType, userID)
|
||||||
id = userID
|
id = userID
|
||||||
}
|
}
|
||||||
token := utils.GetUUID()
|
if loginType2 != "" {
|
||||||
loginInfo = &LoginInfo{
|
loginType = loginType2
|
||||||
ID: id,
|
|
||||||
LoginType: loginType,
|
|
||||||
ExpiresIn: time.Now().Add(DefTokenDuration).Unix(),
|
|
||||||
Token: token,
|
|
||||||
}
|
}
|
||||||
api.Cacher.Set(token, loginInfo, DefTokenDuration)
|
return CreateLoginInfo(id, loginType), nil
|
||||||
globals.SugarLogger.Debugf("Login id:%s, loginType:%s, secret:%s, loginInfo:%s", id, loginType, secret, utils.Format4Output(loginInfo, true))
|
|
||||||
return loginInfo, nil
|
|
||||||
}
|
}
|
||||||
|
err = ConvertErr2NoUser(err, "")
|
||||||
} else {
|
} else {
|
||||||
err = ErrLoginTypeNotSupported
|
err = ErrLoginTypeNotSupported
|
||||||
}
|
}
|
||||||
@@ -92,7 +101,7 @@ func GetUserInfo(token string) (loginInfo *LoginInfo, err error) {
|
|||||||
|
|
||||||
func ConvertErr2NoUser(err error, mobileNum string) error {
|
func ConvertErr2NoUser(err error, mobileNum string) error {
|
||||||
if dao.IsNoRowsError(err) {
|
if dao.IsNoRowsError(err) {
|
||||||
err = fmt.Errorf("没有%s这个用户", mobileNum)
|
err = ErrUserNotExist
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,17 +20,17 @@ func init() {
|
|||||||
auth.RegisterAuther(LoginType, new(Auther))
|
auth.RegisterAuther(LoginType, new(Auther))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Auther) Login(uname, password string) (userID string, err error) {
|
func (a *Auther) Login(uname, password string) (userID, LoginType string, err error) {
|
||||||
user := &legacymodel.JxBackendUser{
|
user := &legacymodel.JxBackendUser{
|
||||||
UName: uname,
|
UName: uname,
|
||||||
}
|
}
|
||||||
if err = dao.GetEntity(nil, user, "UName"); err == nil {
|
if err = dao.GetEntity(nil, user, "UName"); err == nil {
|
||||||
if fmt.Sprintf("%x", md5.Sum([]byte(password))) == user.UPass {
|
if fmt.Sprintf("%x", md5.Sum([]byte(password))) == user.UPass {
|
||||||
return "", nil
|
return "", "", nil
|
||||||
}
|
}
|
||||||
err = auth.ErrUIDAndPassNotMatch
|
err = auth.ErrUIDAndPassNotMatch
|
||||||
}
|
}
|
||||||
return "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Auther) Logout(loginInfo *auth.LoginInfo) error {
|
func (a *Auther) Logout(loginInfo *auth.LoginInfo) error {
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import (
|
|||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxcallback/auth"
|
"git.rosy.net.cn/jx-callback/business/jxcallback/auth"
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
"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"
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
"github.com/KenmyZhang/aliyun-communicate"
|
"github.com/KenmyZhang/aliyun-communicate"
|
||||||
@@ -25,6 +24,10 @@ const (
|
|||||||
LoginType = "mobile"
|
LoginType = "mobile"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrVerifyCodeIsWrong = errors.New("验证码错")
|
||||||
|
)
|
||||||
|
|
||||||
type Auther struct {
|
type Auther struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,35 +56,29 @@ func SendVerifyCode(mobileNumber string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func VerifyCode(mobileNumber, code string) bool {
|
func VerifyCode(mobileNumber, code string) (err error) {
|
||||||
globals.SugarLogger.Debugf("VerifyCode mobileNumber:%s, code:%s", mobileNumber, code)
|
globals.SugarLogger.Debugf("VerifyCode mobileNumber:%s, code:%s", mobileNumber, code)
|
||||||
|
|
||||||
if mobileNumber == TestMobile {
|
err = ErrVerifyCodeIsWrong
|
||||||
return code == TestVerifyCode
|
if mobileNumber == TestMobile && code == TestVerifyCode {
|
||||||
|
err = nil
|
||||||
} else {
|
} else {
|
||||||
if value := api.Cacher.Get(mobileNumber); value != nil {
|
if value := api.Cacher.Get(mobileNumber); value != nil {
|
||||||
if code == value.(string) {
|
if code == value.(string) {
|
||||||
api.Cacher.Del(mobileNumber)
|
api.Cacher.Del(mobileNumber)
|
||||||
return true
|
err = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Auther) Login(mobileNum, verifyCode string) (userID string, err error) {
|
func (a *Auther) Login(mobileNum, verifyCode string) (userID, LoginType string, err error) {
|
||||||
if VerifyCode(mobileNum, verifyCode) {
|
if err = VerifyCode(mobileNum, verifyCode); err == nil {
|
||||||
user := &legacymodel.WeiXins{
|
_, err = dao.GetWeiXinUserByIDs(dao.GetDB(), mobileNum, "", "", "")
|
||||||
Tel: mobileNum,
|
err = auth.ConvertErr2NoUser(err, mobileNum)
|
||||||
}
|
|
||||||
db := dao.GetDB()
|
|
||||||
if err = dao.GetEntity(db, user, "Tel"); err != nil {
|
|
||||||
err = auth.ConvertErr2NoUser(err, mobileNum)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = errors.New("验证错误")
|
|
||||||
}
|
}
|
||||||
return "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Auther) Logout(loginInfo *auth.LoginInfo) error {
|
func (a *Auther) Logout(loginInfo *auth.LoginInfo) error {
|
||||||
|
|||||||
@@ -12,10 +12,8 @@ import (
|
|||||||
"git.rosy.net.cn/jx-callback/business/jxcallback/auth/mobile"
|
"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/jxutils/jxcontext"
|
||||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
"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"
|
||||||
"git.rosy.net.cn/jx-callback/globals/api"
|
"git.rosy.net.cn/jx-callback/globals/api"
|
||||||
"github.com/astaxie/beego/orm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -31,7 +29,6 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrLoginFailed = errors.New("登录失败")
|
|
||||||
StrStateIsWrong = "state:%s状态不对"
|
StrStateIsWrong = "state:%s状态不对"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -40,6 +37,10 @@ var (
|
|||||||
AutherMini *AutherMiniProgram
|
AutherMini *AutherMiniProgram
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrExceptionalLogin = errors.New("登录异常,无前置微信授权操作")
|
||||||
|
)
|
||||||
|
|
||||||
type Auther struct {
|
type Auther struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +49,8 @@ type AutherMiniProgram struct {
|
|||||||
|
|
||||||
type UserInfoExt struct {
|
type UserInfoExt struct {
|
||||||
weixinapi.SNSUserInfo
|
weixinapi.SNSUserInfo
|
||||||
TempPassword string `json:"tempPassword"` // 一段时间有效的登录密码
|
TempPassword string `json:"tempPassword"` // 一段时间有效的登录密码
|
||||||
|
LoginInfo *auth.LoginInfo `json:"loginInfo"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -59,21 +61,41 @@ func init() {
|
|||||||
auth.RegisterAuther(LoginTypeMiniProgram, AutherMini)
|
auth.RegisterAuther(LoginTypeMiniProgram, AutherMini)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetUserInfo(code string, state string) (token *UserInfoExt, err error) {
|
func cacheSNSInfo(wxUserinfo *weixinapi.SNSUserInfo, password string, duration time.Duration) {
|
||||||
globals.SugarLogger.Debugf("GetUserInfo code:%s", code)
|
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 == "" {
|
if state == "" {
|
||||||
token, err2 := api.WeixinAPI.SNSGetToken(code)
|
token, err2 := api.WeixinAPI.SNSGetToken(code)
|
||||||
if err = err2; err == nil {
|
if err = err2; err == nil {
|
||||||
wxUserinfo, err2 := api.WeixinAPI.SNSGetUserInfo(token.AccessToken, token.OpenID)
|
wxUserinfo, err2 := api.WeixinAPI.SNSGetUserInfo(token.AccessToken, token.OpenID)
|
||||||
if err = err2; err == nil {
|
if err = err2; err == nil {
|
||||||
pwd := utils.GetUUID()
|
userInfo = &UserInfoExt{
|
||||||
globals.SugarLogger.Debugf("GetUserInfo code:%s, pwd:%s", code, pwd)
|
|
||||||
api.Cacher.Set(wxUserinfo.OpenID, pwd, DefTempPasswordDuration)
|
|
||||||
return &UserInfoExt{
|
|
||||||
SNSUserInfo: *wxUserinfo,
|
SNSUserInfo: *wxUserinfo,
|
||||||
TempPassword: pwd,
|
TempPassword: utils.GetUUID(),
|
||||||
}, nil
|
}
|
||||||
|
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 {
|
} else {
|
||||||
@@ -82,23 +104,15 @@ func GetUserInfo(code string, state string) (token *UserInfoExt, err error) {
|
|||||||
return nil, err
|
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)
|
globals.SugarLogger.Debugf("weixinsns Login openid:%s, password:%s", openid, password)
|
||||||
|
_, cachedPwd := getSNSInfoFromCache(openid)
|
||||||
if value := api.Cacher.Get(openid); value != nil {
|
if cachedPwd != "" && password == cachedPwd {
|
||||||
if password == value.(string) {
|
api.Cacher.Del(openid)
|
||||||
// wxUser := &legacymodel.WeiXins{
|
return "", "", nil
|
||||||
// OpenID: openid,
|
|
||||||
// }
|
|
||||||
// if err = dao.GetEntity(nil, wxUser, "OpenID"); err == nil {
|
|
||||||
api.Cacher.Del(openid)
|
|
||||||
return "", nil
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = ErrLoginFailed
|
|
||||||
}
|
}
|
||||||
return "", err
|
return "", "", ErrExceptionalLogin
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Auther) Logout(loginInfo *auth.LoginInfo) error {
|
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) {
|
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)
|
loginInfo := new(auth.LoginInfo)
|
||||||
if err = api.Cacher.GetAs(token, loginInfo); err == nil {
|
if err = api.Cacher.GetAs(token, loginInfo); err == nil {
|
||||||
if mobile.VerifyCode(mobileNum, code) {
|
if err = mobile.VerifyCode(mobileNum, code); err == nil {
|
||||||
user := &legacymodel.WeiXins{
|
wxUserinfo, _ := getSNSInfoFromCache(loginInfo.ID)
|
||||||
OpenID: loginInfo.ID,
|
if wxUserinfo == nil {
|
||||||
Tel: mobileNum,
|
return fmt.Errorf("绑定超时,请重新绑定")
|
||||||
NickName: nickname,
|
|
||||||
ParentID: -1,
|
|
||||||
}
|
}
|
||||||
db := dao.GetDB()
|
if nickname == "" {
|
||||||
if err = dao.GetEntity(db, user, "OpenID"); err == nil {
|
nickname = wxUserinfo.NickName
|
||||||
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 err == orm.ErrNoRows {
|
err = auth.ConvertErr2NoUser(dao.UpdateWeiXinUser(dao.GetDB(), mobileNum, nickname, wxUserinfo.UnionID, wxUserinfo.OpenID, ""), mobileNum)
|
||||||
err = dao.CreateEntity(db, user)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = errors.New("验证码错")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err
|
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,用户必须先在后台创建(手机号标识)
|
// 1,用户必须先在后台创建(手机号标识)
|
||||||
// 2,用户必须先绑定微信
|
// 2,用户必须先绑定微信
|
||||||
@@ -155,46 +181,51 @@ func (a *AutherMiniProgram) BindWeiXin(ctx *jxcontext.Context, code, nickName st
|
|||||||
if loginInfo == nil || loginInfo.LoginType != mobile.LoginType {
|
if loginInfo == nil || loginInfo.LoginType != mobile.LoginType {
|
||||||
return fmt.Errorf("调用AutherMiniProgram BindWeiXin时,必须以手机验证方式登录")
|
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)
|
sessionInfo, err := api.WeixinMiniAPI.SNSCode2Session(code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
user.OpenIDMini = sessionInfo.OpenID
|
err = dao.UpdateWeiXinUser(dao.GetDB(), loginInfo.ID, nickName, sessionInfo.UnionID, "", sessionInfo.OpenID)
|
||||||
cols := []string{"OpenIDMini"}
|
return auth.ConvertErr2NoUser(err, "")
|
||||||
if nickName != "" {
|
|
||||||
user.NickName = nickName
|
|
||||||
cols = append(cols, "NickName")
|
|
||||||
}
|
|
||||||
_, err = dao.UpdateEntity(db, user, cols...)
|
|
||||||
return 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)
|
globals.SugarLogger.Debugf("AutherMiniProgram Login mobileNum:%s, code:%s", mobileNum, code)
|
||||||
sessionInfo, err := api.WeixinMiniAPI.SNSCode2Session(code)
|
sessionInfo, err := api.WeixinMiniAPI.SNSCode2Session(code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", "", err
|
||||||
}
|
|
||||||
user := &legacymodel.WeiXins{
|
|
||||||
OpenIDMini: sessionInfo.OpenID,
|
|
||||||
}
|
}
|
||||||
db := dao.GetDB()
|
db := dao.GetDB()
|
||||||
if err = dao.GetEntity(db, user, "OpenIDMini"); err != nil {
|
user, err := dao.GetWeiXinUserByIDs(db, "", sessionInfo.UnionID, "", sessionInfo.OpenID)
|
||||||
return "", auth.ConvertErr2NoUser(err, mobileNum)
|
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)
|
globals.SugarLogger.Debugf("AutherMiniProgram Login user.Tel:%s, code:%s, openID:%s", user.Tel, code, sessionInfo.OpenID)
|
||||||
if mobileNum != user.Tel {
|
if mobileNum != user.Tel {
|
||||||
|
|
||||||
}
|
}
|
||||||
api.Cacher.Set(composeSessionKeyCacheKey(sessionInfo.OpenID), sessionInfo.SessionKey, auth.DefTokenDuration)
|
api.Cacher.Set(composeSessionKeyCacheKey(user.Tel), sessionInfo.SessionKey, auth.DefTokenDuration)
|
||||||
return sessionInfo.OpenID, err
|
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 {
|
func (a *AutherMiniProgram) Logout(loginInfo *auth.LoginInfo) error {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ func CreateWeiXins(db *DaoDB, user *legacymodel.WeiXins) (err error) {
|
|||||||
SET
|
SET
|
||||||
openid = IF(openid = '', NULL, openid),
|
openid = IF(openid = '', NULL, openid),
|
||||||
openid_mini = IF(openid_mini = '', NULL, openid_mini),
|
openid_mini = IF(openid_mini = '', NULL, openid_mini),
|
||||||
|
openid_union = IF(openid_union = '', NULL, openid_union),
|
||||||
tel = IF(tel = '', NULL, tel)
|
tel = IF(tel = '', NULL, tel)
|
||||||
WHERE id = ?
|
WHERE id = ?
|
||||||
`, user.ID); err != nil {
|
`, user.ID); err != nil {
|
||||||
@@ -24,3 +25,59 @@ func CreateWeiXins(db *DaoDB, user *legacymodel.WeiXins) (err error) {
|
|||||||
Commit(db)
|
Commit(db)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetWeiXinUserByIDs(db *DaoDB, tel, unionID, openID, miniOpenID string) (user *legacymodel.WeiXins, err error) {
|
||||||
|
fieldList := []string{
|
||||||
|
"Tel",
|
||||||
|
"OpenIDUnion",
|
||||||
|
"OpenID",
|
||||||
|
"OpenIDMini",
|
||||||
|
}
|
||||||
|
valueList := []string{
|
||||||
|
tel,
|
||||||
|
unionID,
|
||||||
|
openID,
|
||||||
|
miniOpenID,
|
||||||
|
}
|
||||||
|
user = &legacymodel.WeiXins{
|
||||||
|
Tel: tel,
|
||||||
|
OpenIDUnion: unionID,
|
||||||
|
OpenID: openID,
|
||||||
|
OpenIDMini: miniOpenID,
|
||||||
|
}
|
||||||
|
for index := range valueList {
|
||||||
|
if valueList[index] != "" {
|
||||||
|
if err = GetEntity(db, user, fieldList[index]); err == nil {
|
||||||
|
return user, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateWeiXinUser(db *DaoDB, tel, nickname, unionID, openID, miniOpenID string) (err error) {
|
||||||
|
user := &legacymodel.WeiXins{
|
||||||
|
Tel: tel,
|
||||||
|
}
|
||||||
|
if err = GetEntity(db, user, "Tel"); err == nil {
|
||||||
|
updateFields := []string{}
|
||||||
|
if openID != "" {
|
||||||
|
user.OpenID = openID
|
||||||
|
updateFields = append(updateFields, "OpenID")
|
||||||
|
}
|
||||||
|
if unionID != "" {
|
||||||
|
user.OpenIDUnion = unionID
|
||||||
|
updateFields = append(updateFields, "OpenIDUnion")
|
||||||
|
}
|
||||||
|
if miniOpenID != "" {
|
||||||
|
user.OpenIDMini = miniOpenID
|
||||||
|
updateFields = append(updateFields, "OpenIDMini")
|
||||||
|
}
|
||||||
|
if nickname != "" {
|
||||||
|
user.NickName = nickname
|
||||||
|
updateFields = append(updateFields, "NickName")
|
||||||
|
}
|
||||||
|
_, err = UpdateEntity(db, user, updateFields...)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
34
business/model/dao/dao_user_test.go
Normal file
34
business/model/dao/dao_user_test.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model/legacymodel"
|
||||||
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCreateWeiXins(t *testing.T) {
|
||||||
|
err := CreateWeiXins(GetDB(), &legacymodel.WeiXins{
|
||||||
|
Tel: "12345",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
// globals.SugarLogger.Debug(utils.Format4Output(places, false))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetWeiXinUserByIDs(t *testing.T) {
|
||||||
|
user, err := GetWeiXinUserByIDs(GetDB(), "", "unionid", "", "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
globals.SugarLogger.Debug(utils.Format4Output(user, false))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdateWeiXinUser(t *testing.T) {
|
||||||
|
err := UpdateWeiXinUser(GetDB(), "12345", "nickname", "unionid", "openid", "miniid")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ const (
|
|||||||
ErrCodeSuccess = "0"
|
ErrCodeSuccess = "0"
|
||||||
ErrCodeGeneralFailed = "-1"
|
ErrCodeGeneralFailed = "-1"
|
||||||
ErrCodeTokenIsInvalid = "-2"
|
ErrCodeTokenIsInvalid = "-2"
|
||||||
|
ErrCodeUserNotExist = "-3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
package legacymodel
|
package legacymodel
|
||||||
|
|
||||||
type WeiXins struct {
|
type WeiXins struct {
|
||||||
ID int `orm:"column(id)" json:"id"`
|
ID int `orm:"column(id)" json:"id"`
|
||||||
JxStoreID int `orm:"column(jxstoreid);index" json:"storeID"`
|
JxStoreID int `orm:"column(jxstoreid);index" json:"storeID"`
|
||||||
OpenID string `orm:"column(openid);size(70);unique;null" json:"-"`
|
OpenID string `orm:"column(openid);size(70);unique;null" json:"-"`
|
||||||
OpenIDMini string `orm:"column(openid_mini);size(70);unique;null" json:"-"`
|
OpenIDMini string `orm:"column(openid_mini);size(70);unique;null" json:"-"`
|
||||||
Tel string `orm:"size(15);null;unique" json:"tel"`
|
OpenIDUnion string `orm:"column(openid_union);size(70);unique;null" json:"-"`
|
||||||
ParentID int `orm:"column(parentid);default(-1);index" json:"parentID"`
|
Tel string `orm:"size(15);null;unique" json:"tel"`
|
||||||
NickName string `orm:"column(nickname);size(30)" json:"nickname"`
|
ParentID int `orm:"column(parentid);default(-1);index" json:"parentID"`
|
||||||
|
NickName string `orm:"column(nickname);size(30)" json:"nickname"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*WeiXins) TableName() string {
|
func (*WeiXins) TableName() string {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
_ "git.rosy.net.cn/jx-callback/business/jxcallback/auth/localpass" // 加载本地用户密码
|
_ "git.rosy.net.cn/jx-callback/business/jxcallback/auth/localpass" // 加载本地用户密码
|
||||||
"git.rosy.net.cn/jx-callback/business/jxcallback/auth/mobile"
|
"git.rosy.net.cn/jx-callback/business/jxcallback/auth/mobile"
|
||||||
"git.rosy.net.cn/jx-callback/business/jxcallback/auth/weixin"
|
"git.rosy.net.cn/jx-callback/business/jxcallback/auth/weixin"
|
||||||
|
"git.rosy.net.cn/jx-callback/business/model"
|
||||||
"git.rosy.net.cn/jx-callback/globals"
|
"git.rosy.net.cn/jx-callback/globals"
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
)
|
)
|
||||||
@@ -45,7 +46,7 @@ func (c *AuthController) GetWeiXinUserInfo() {
|
|||||||
state := c.GetString("state")
|
state := c.GetString("state")
|
||||||
if block != "" {
|
if block != "" {
|
||||||
if code != "" {
|
if code != "" {
|
||||||
result, err2 := weixin.GetUserInfo(code, state)
|
result, err2 := weixin.GetWeiXinUserInfo(code, state)
|
||||||
if err = err2; err == nil {
|
if err = err2; err == nil {
|
||||||
retVal.Code = 1
|
retVal.Code = 1
|
||||||
retVal.Msg = "微信登录成功"
|
retVal.Msg = "微信登录成功"
|
||||||
@@ -73,6 +74,9 @@ func (c *AuthController) GetWeiXinUserInfo() {
|
|||||||
func (c *AuthController) Login() {
|
func (c *AuthController) Login() {
|
||||||
c.callLogin(func(params *tAuthLoginParams) (retVal interface{}, errCode string, err error) {
|
c.callLogin(func(params *tAuthLoginParams) (retVal interface{}, errCode string, err error) {
|
||||||
retVal, err = auth.Login(params.Id, params.Type, params.Secret)
|
retVal, err = auth.Login(params.Id, params.Type, params.Secret)
|
||||||
|
if err == auth.ErrUserNotExist {
|
||||||
|
return retVal, model.ErrCodeUserNotExist, err
|
||||||
|
}
|
||||||
return retVal, "", err
|
return retVal, "", err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -129,6 +133,9 @@ func (c *AuthController) SendMobileVerifyCode() {
|
|||||||
func (c *AuthController) BindMobile() {
|
func (c *AuthController) BindMobile() {
|
||||||
c.callBindMobile(func(params *tAuthBindMobileParams) (retVal interface{}, errCode string, err error) {
|
c.callBindMobile(func(params *tAuthBindMobileParams) (retVal interface{}, errCode string, err error) {
|
||||||
err = weixin.BindMobile(params.Token, params.Mobile, params.Code, params.Nickname)
|
err = weixin.BindMobile(params.Token, params.Mobile, params.Code, params.Nickname)
|
||||||
|
if err == auth.ErrUserNotExist {
|
||||||
|
return retVal, model.ErrCodeUserNotExist, err
|
||||||
|
}
|
||||||
return retVal, "", err
|
return retVal, "", err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -144,6 +151,9 @@ func (c *AuthController) BindMobile() {
|
|||||||
func (c *AuthController) MiniBindWeiXin() {
|
func (c *AuthController) MiniBindWeiXin() {
|
||||||
c.callMiniBindWeiXin(func(params *tAuthMiniBindWeiXinParams) (retVal interface{}, errCode string, err error) {
|
c.callMiniBindWeiXin(func(params *tAuthMiniBindWeiXinParams) (retVal interface{}, errCode string, err error) {
|
||||||
err = weixin.AutherMini.BindWeiXin(params.Ctx, params.Code, params.Nickname)
|
err = weixin.AutherMini.BindWeiXin(params.Ctx, params.Code, params.Nickname)
|
||||||
|
if err == auth.ErrUserNotExist {
|
||||||
|
return retVal, model.ErrCodeUserNotExist, err
|
||||||
|
}
|
||||||
return retVal, "", err
|
return retVal, "", err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -162,3 +172,23 @@ func (c *AuthController) MiniDecryptData() {
|
|||||||
return retVal, "", err
|
return retVal, "", err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Title 微信公众号绑定手机2
|
||||||
|
// @Description 微信公众号绑定手机2
|
||||||
|
// @Param openID formData string true "微信公众号ID"
|
||||||
|
// @Param secret formData string true "后台之前返回的secret"
|
||||||
|
// @Param nickname formData string false "用户名"
|
||||||
|
// @Param mobile formData string true "手机号"
|
||||||
|
// @Param verifyCode formData string true "手机验证码"
|
||||||
|
// @Success 200 {object} controllers.CallResult
|
||||||
|
// @Failure 200 {object} controllers.CallResult
|
||||||
|
// @router /BindMobile2 [post]
|
||||||
|
func (c *AuthController) BindMobile2() {
|
||||||
|
c.callBindMobile2(func(params *tAuthBindMobile2Params) (retVal interface{}, errCode string, err error) {
|
||||||
|
retVal, err = weixin.BindMobile2(params.OpenID, params.Secret, params.Mobile, params.VerifyCode, params.Nickname)
|
||||||
|
if err == auth.ErrUserNotExist {
|
||||||
|
return retVal, model.ErrCodeUserNotExist, err
|
||||||
|
}
|
||||||
|
return retVal, "", err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,14 @@ func init() {
|
|||||||
MethodParams: param.Make(),
|
MethodParams: param.Make(),
|
||||||
Params: nil})
|
Params: nil})
|
||||||
|
|
||||||
|
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:AuthController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:AuthController"],
|
||||||
|
beego.ControllerComments{
|
||||||
|
Method: "BindMobile2",
|
||||||
|
Router: `/BindMobile2`,
|
||||||
|
AllowHTTPMethods: []string{"post"},
|
||||||
|
MethodParams: param.Make(),
|
||||||
|
Params: nil})
|
||||||
|
|
||||||
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:AuthController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:AuthController"],
|
beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:AuthController"] = append(beego.GlobalControllerRouter["git.rosy.net.cn/jx-callback/controllers:AuthController"],
|
||||||
beego.ControllerComments{
|
beego.ControllerComments{
|
||||||
Method: "GetUserInfo",
|
Method: "GetUserInfo",
|
||||||
|
|||||||
Reference in New Issue
Block a user