- mini program login

This commit is contained in:
gazebo
2018-12-27 16:49:32 +08:00
parent b1a7cfdaa8
commit 5adc5e61f3
16 changed files with 301 additions and 51 deletions

View File

@@ -2,10 +2,12 @@ package auth
import (
"errors"
"fmt"
"time"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/globals/api"
)
@@ -14,8 +16,8 @@ const (
)
type IAuther interface {
Login(id, secret string) error
Logout(id string) error
Login(id, secret string) (userID string, err error)
Logout(loginInfo *LoginInfo) error
}
var (
@@ -44,7 +46,11 @@ func RegisterAuther(loginType string, handler IAuther) {
func Login(id, loginType, secret string) (loginInfo *LoginInfo, err error) {
if handler := authers[loginType]; handler != nil {
if err = handler.Login(id, secret); err == nil {
userID, err2 := handler.Login(id, secret)
if err = err2; err == nil {
if userID != "" {
id = userID
}
token := utils.GetUUID()
loginInfo = &LoginInfo{
ID: id,
@@ -65,7 +71,7 @@ func Logout(token string) (err error) {
loginInfo := new(LoginInfo)
if err = api.Cacher.GetAs(token, loginInfo); err == nil {
if handler := authers[loginInfo.LoginType]; handler != nil {
err = handler.Logout(loginInfo.ID)
err = handler.Logout(loginInfo)
}
api.Cacher.Del(token)
}
@@ -79,3 +85,10 @@ func GetUserInfo(token string) (loginInfo *LoginInfo, err error) {
}
return nil, model.ErrTokenIsInvalid
}
func ConvertErr2NoUser(err error, mobileNum string) error {
if dao.IsNoRowsError(err) {
err = fmt.Errorf("没有%s这个用户", mobileNum)
}
return err
}

View File

@@ -20,19 +20,19 @@ func init() {
auth.RegisterAuther(LoginType, new(Auther))
}
func (a *Auther) Login(uname, password string) (err error) {
func (a *Auther) Login(uname, password string) (userID string, err error) {
user := &legacymodel.JxBackendUser{
UName: uname,
}
if err = dao.GetEntity(nil, user, "UName"); err == nil {
if fmt.Sprintf("%x", md5.Sum([]byte(password))) == user.UPass {
return nil
return "", nil
}
err = auth.ErrUIDAndPassNotMatch
}
return err
return "", err
}
func (a *Auther) Logout(openid string) error {
func (a *Auther) Logout(loginInfo *auth.LoginInfo) error {
return nil
}

View File

@@ -1,11 +1,15 @@
package mobile
import (
"errors"
"fmt"
"math/rand"
"time"
"git.rosy.net.cn/baseapi/utils"
"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/legacymodel"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
"github.com/KenmyZhang/aliyun-communicate"
@@ -15,6 +19,22 @@ const (
DefVerifyCodeDuration = 5 * time.Minute
)
const (
LoginType = "mobile"
)
type Auther struct {
}
var (
auther *Auther
)
func init() {
auther = new(Auther)
auth.RegisterAuther(LoginType, auther)
}
func SendVerifyCode(mobileNumber string) error {
code := fmt.Sprintf("%06d", rand.Intn(1000000))
globals.SugarLogger.Debugf("SendVerifyCode mobileNumber:%s, code:%s", mobileNumber, code)
@@ -42,3 +62,22 @@ func VerifyCode(mobileNumber, code string) bool {
}
return false
}
func (a *Auther) Login(mobileNum, verifyCode string) (userID string, err error) {
if VerifyCode(mobileNum, verifyCode) {
user := &legacymodel.WeiXins{
Tel: mobileNum,
}
db := dao.GetDB()
if err = dao.GetEntity(db, user, "Tel"); err != nil {
err = auth.ConvertErr2NoUser(err, mobileNum)
}
} else {
err = errors.New("验证错误")
}
return "", err
}
func (a *Auther) Logout(loginInfo *auth.LoginInfo) error {
return nil
}

View File

@@ -1,6 +1,7 @@
package weixin
import (
"encoding/base64"
"errors"
"fmt"
"time"
@@ -9,6 +10,7 @@ import (
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxcallback/auth"
"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"
@@ -18,21 +20,32 @@ import (
const (
LoginType = "weixinsns"
LoginTypeMiniProgram = "weixinmini"
DefTempPasswordDuration = 5 * time.Minute // 登录时间限制在5分钟内
)
const (
CacheKeySeparator = "/"
MiniVerifyCodePrefix = "MiniVerifyCode"
SessionKeyPrefix = "SessionKey"
)
var (
ErrLoginFailed = errors.New("登录失败")
StrStateIsWrong = "state:%s状态不对"
)
var (
auther *Auther
auther *Auther
AutherMini *AutherMiniProgram
)
type Auther struct {
}
type AutherMiniProgram struct {
}
type UserInfoExt struct {
weixinapi.SNSUserInfo
TempPassword string `json:"tempPassword"` // 一段时间有效的登录密码
@@ -41,6 +54,9 @@ type UserInfoExt struct {
func init() {
auther = new(Auther)
auth.RegisterAuther(LoginType, auther)
AutherMini = new(AutherMiniProgram)
auth.RegisterAuther(LoginTypeMiniProgram, AutherMini)
}
func GetUserInfo(code string, state string) (token *UserInfoExt, err error) {
@@ -66,8 +82,8 @@ func GetUserInfo(code string, state string) (token *UserInfoExt, err error) {
return nil, err
}
func (a *Auther) Login(openid, password string) (err error) {
globals.SugarLogger.Debugf("Login openid:%s, password:%s", openid, password)
func (a *Auther) Login(openid, password string) (userID 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) {
@@ -76,17 +92,17 @@ func (a *Auther) Login(openid, password string) (err error) {
// }
// if err = dao.GetEntity(nil, wxUser, "OpenID"); err == nil {
api.Cacher.Del(openid)
return nil
return "", nil
// }
}
} else {
err = ErrLoginFailed
}
return err
return "", err
}
func (a *Auther) Logout(openid string) error {
return api.Cacher.Del(openid)
func (a *Auther) Logout(loginInfo *auth.LoginInfo) error {
return nil
}
func BindMobile(token, mobileNum, code, nickname string) (err error) {
@@ -122,3 +138,84 @@ func BindMobile(token, mobileNum, code, nickname string) (err error) {
}
return err
}
// 对于小程序来说,
// 1用户必须先在后台创建手机号标识
// 2用户必须先绑定微信
// 先以短信方式登录:
// SendMobileVerifyCode
// Login use type mobile
// MiniBindWeiXin
// 3用户以CODE来登录Login use type weixinmini
// Login
func (a *AutherMiniProgram) BindWeiXin(ctx *jxcontext.Context, code, nickName string) (err error) {
globals.SugarLogger.Debugf("AutherMiniProgram BindWeiXin code:%s, nickName:%s", code, nickName)
loginInfo := ctx.GetLoginInfo()
if 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.WeixinAPI.SNSCode2Session(code)
if err != nil {
return err
}
user.OpenIDMini = sessionInfo.OpenID
if nickName != "" {
user.NickName = nickName
}
_, err = dao.UpdateEntity(db, user)
return err
}
func (a *AutherMiniProgram) Login(mobileNum, code string) (userID string, err error) {
globals.SugarLogger.Debugf("AutherMiniProgram Login mobileNum:%s, code:%s", mobileNum, code)
sessionInfo, err := api.WeixinAPI.SNSCode2Session(code)
if err != nil {
return "", err
}
user := &legacymodel.WeiXins{
OpenIDMini: sessionInfo.OpenID,
}
db := dao.GetDB()
if err = dao.GetEntity(db, user, "OpenIDMini"); err != nil {
return "", auth.ConvertErr2NoUser(err, mobileNum)
}
if mobileNum != user.Tel {
}
api.Cacher.Set(composeSessionKeyCacheKey(sessionInfo.OpenID), sessionInfo.SessionKey, auth.DefTokenDuration)
return sessionInfo.OpenID, err
}
func (a *AutherMiniProgram) Logout(loginInfo *auth.LoginInfo) error {
globals.SugarLogger.Debugf("AutherMiniProgram Logout openid:%s", utils.Format4Output(loginInfo, false))
return api.Cacher.Del(composeSessionKeyCacheKey(loginInfo.ID))
}
func (a *AutherMiniProgram) DecryptData(ctx *jxcontext.Context, encryptedData, iv string) (decryptedDataBase64 string, err error) {
globals.SugarLogger.Debugf("AutherMiniProgram DecryptData encryptedData:%s, iv:%s", encryptedData, iv)
var sessionKey string
if err = api.Cacher.GetAs(composeSessionKeyCacheKey(ctx.GetLoginInfo().ID), &sessionKey); err != nil {
return "", err
}
decryptedData, err := api.WeixinAPI.SNSDecodeMiniProgramData(encryptedData, sessionKey, iv)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(decryptedData), nil
}
func composeMiniVerifiyCacheKey(key string) string {
return MiniVerifyCodePrefix + CacheKeySeparator + key
}
func composeSessionKeyCacheKey(key string) string {
return SessionKeyPrefix + CacheKeySeparator + key
}