xdd-plus/controllers/login.go
2021-09-19 22:41:37 +08:00

524 lines
14 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package controllers
import (
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"regexp"
"strings"
"sync"
"time"
"github.com/beego/beego/v2/core/logs"
"github.com/cdle/xdd/models"
"github.com/beego/beego/v2/client/httplib"
qrcode "github.com/skip2/go-qrcode"
)
type LoginController struct {
BaseController
}
type StepOne struct {
SToken string `json:"s_token"`
}
type StepTwo struct {
Token string `json:"token"`
}
type StepThree struct {
CheckIP int `json:"check_ip"`
Errcode int `json:"errcode"`
Message string `json:"message"`
}
type Result struct {
Code int `json:"code"`
Data interface{} `json:"data"`
Message string `json:"message"`
}
var JdCookieRunners sync.Map
var jdua = models.GetUserAgent
func (c *LoginController) GetQrcode() {
if v := c.GetSession("jd_token"); v != nil {
token := v.(string)
if v, ok := JdCookieRunners.Load(token); ok {
if len(v.([]interface{})) >= 2 {
var url = `https://plogin.m.jd.com/cgi-bin/m/tmauth?appid=300&client_type=m&token=` + token
data, _ := qrcode.Encode(url, qrcode.Medium, 256)
c.Ctx.WriteString(`{"url":"` + url + `","img":"` + base64.StdEncoding.EncodeToString(data) + `"}`)
return
}
}
}
var state = time.Now().Unix()
var url = fmt.Sprintf(`https://plogin.m.jd.com/cgi-bin/mm/new_login_entrance?lang=chs&appid=300&returnurl=https://wq.jd.com/passport/LoginRedirect?state=%d&returnurl=https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport`,
state)
req := httplib.Get(url)
req.Header("Connection", "Keep-Alive")
req.Header("Content-Type", "application/x-www-form-urlencoded")
req.Header("Accept", "application/json, text/plain, */*")
req.Header("Accept-Language", "zh-cn")
req.Header("Referer", url)
req.Header("User-Agent", jdua())
req.Header("Host", "plogin.m.jd.com")
rsp, err := req.Response()
if err != nil {
c.Ctx.WriteString(err.Error())
return
}
data, err := ioutil.ReadAll(rsp.Body)
so := StepOne{}
err = json.Unmarshal(data, &so)
if err != nil {
c.Ctx.WriteString(err.Error())
return
}
cookies := strings.Join(rsp.Header.Values("Set-Cookie"), " ")
var cookie = strings.Join([]string{
"guid=" + FetchJdCookieValue("guid", cookies),
"lang=chs",
"lsid=" + FetchJdCookieValue("lsid", cookies),
"lstoken=" + FetchJdCookieValue("lstoken", cookies),
}, ";")
state = time.Now().Unix()
req = httplib.Post(
fmt.Sprintf(`https://plogin.m.jd.com/cgi-bin/m/tmauthreflogurl?s_token=%s&v=%d&remember=true`,
so.SToken,
state),
)
req.Header("Connection", "Keep-Alive")
req.Header("Content-Type", "application/x-www-form-urlencoded; Charset=UTF-8")
req.Header("Accept", "application/json, text/plain, */*")
req.Header("Cookie", cookie)
req.Header("Referer", fmt.Sprintf(`https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wqlogin2.jd.com/passport/LoginRedirect?state=%d&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport`,
state),
)
req.Header("User-Agent", jdua())
req.Header("Host", "plogin.m.jd.com")
req.Body(fmt.Sprintf(`{
'lang': 'chs',
'appid': 300,
'returnurl': 'https://wqlogin2.jd.com/passport/LoginRedirect?state=%dreturnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport',
}`, state))
rsp, err = req.Response()
if err != nil {
c.Ctx.WriteString(err.Error())
return
}
data, err = ioutil.ReadAll(rsp.Body)
st := StepTwo{}
err = json.Unmarshal(data, &st)
if err != nil {
c.Ctx.WriteString(err.Error())
return
}
url = `https://plogin.m.jd.com/cgi-bin/m/tmauth?client_type=m&appid=300&token=` + st.Token
cookies = strings.Join(rsp.Header.Values("Set-Cookie"), " ")
okl_token := FetchJdCookieValue("okl_token", cookies)
data, _ = qrcode.Encode(url, qrcode.Medium, 256)
bot := c.GetString("tp")
uid := c.GetQueryInt("uid")
gid := c.GetQueryInt("gid")
mid := c.GetQueryInt("mid")
unm := c.GetString("unm")
JdCookieRunners.Store(st.Token, []interface{}{cookie, okl_token, bot, uid, gid, mid, unm})
if bot != "" {
c.Ctx.ResponseWriter.Write(data)
return
}
c.SetSession("jd_token", st.Token)
c.SetSession("jd_cookie", cookie)
c.SetSession("jd_okl_token", okl_token)
c.Ctx.WriteString(`{"url":"` + url + `","img":"` + base64.StdEncoding.EncodeToString(data) + `"}`) //"data:image/png;base64," +
}
func init() {
go func() {
for {
time.Sleep(time.Second)
JdCookieRunners.Range(func(k, v interface{}) bool {
jd_token := k.(string)
vv := v.([]interface{})
if len(vv) >= 2 {
cookie := vv[0].(string)
okl_token := vv[1].(string)
bot := vv[2].(string)
uid := vv[3].(int)
gid := vv[4].(int)
// fmt.Println(jd_token, cookie, okl_token)
result, ck := CheckLogin(jd_token, cookie, okl_token)
// fmt.Println(result)
switch result {
case "成功":
switch bot {
case "qq", "qqg":
ck.Update(models.QQ, uid)
if gid != 0 {
go models.SendQQGroup(int64(gid), int64(uid), "扫码成功")
} else {
go models.SendQQ(int64(uid), "扫码成功")
}
case "tg", "tgg":
ck.Update(models.Telegram, uid)
if ck.Priority < 0 && models.GetEnv("AutoPriority") == models.True {
ck.Update(models.Priority, -ck.Priority)
}
if gid != 0 {
go models.SendTggMsg(int(gid), int(uid), "扫码成功", vv[5].(int), vv[6].(string))
} else {
go models.SendTgMsg(int(uid), "扫码成功")
}
}
case "授权登录未确认":
case "":
default: //失效
switch bot {
case "qq", "qqg":
// ck.Update(models.QQ, uid)
if gid != 0 {
go models.SendQQGroup(int64(gid), int64(uid), "扫码失败")
} else {
go models.SendQQ(int64(uid), "扫码失败")
}
case "tg", "tgg":
// ck.Update(models.Telegram, uid)
if gid != 0 {
go models.SendTggMsg(int(gid), int(uid), "扫码失败", vv[5].(int), vv[6].(string))
} else {
go models.SendTgMsg(int(uid), "扫码失败")
}
}
}
}
return true
})
}
}()
}
//Query 查询
func (c *LoginController) Query() {
if v := c.GetSession("jd_token"); v == nil {
c.Ctx.WriteString("重新获取二维码")
return
} else {
token := v.(string)
if v, ok := JdCookieRunners.Load(token); !ok {
c.Ctx.WriteString("重新获取二维码")
return
} else {
if len(v.([]interface{})) >= 2 {
c.Ctx.WriteString("授权登录未确认")
return
} else {
pin := v.([]interface{})[0].(string)
c.SetSession("pin", pin)
if note := c.GetString("note"); note != "" {
if ck, err := models.GetJdCookie(pin); err == nil {
ck.Update(models.Note, note)
}
}
// if strings.Contains(models.Config.Master, pin) {
c.Ctx.WriteString("登录")
// } else {
// c.Ctx.WriteString("成功")
// }
return
}
}
}
}
func CheckLogin(token, cookie, okl_token string) (string, *models.JdCookie) {
state := time.Now().Unix()
req := httplib.Post(
fmt.Sprintf(`https://plogin.m.jd.com/cgi-bin/m/tmauthchecktoken?&token=%s&ou_state=0&okl_token=%s`,
token,
okl_token,
),
)
req.Header("Referer", fmt.Sprintf(`https://plogin.m.jd.com/login/login?appid=300&returnurl=https://wqlogin2.jd.com/passport/LoginRedirect?state=%d&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action&source=wq_passport`,
state),
)
req.Header("Cookie", cookie)
req.Header("Connection", "Keep-Alive")
req.Header("Content-Type", "application/x-www-form-urlencoded; Charset=UTF-8")
req.Header("Accept", "application/json, text/plain, */*")
req.Header("User-Agent", jdua())
req.Header("Host", "plogin.m.jd.com")
req.Param("lang", "chs")
req.Param("appid", "300")
req.Param("returnurl", fmt.Sprintf("https://wqlogin2.jd.com/passport/LoginRedirect?state=%d&returnurl=//home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&/myJd/home.action", state))
req.Param("source", "wq_passport")
rsp, err := req.Response()
if err != nil {
return "", nil //err.Error()
}
data, err := ioutil.ReadAll(rsp.Body)
sth := StepThree{}
err = json.Unmarshal(data, &sth)
if err != nil {
return "", nil //err.Error()
}
switch sth.Errcode {
case 0:
cookies := strings.Join(rsp.Header.Values("Set-Cookie"), " ")
pt_key := FetchJdCookieValue("pt_key", cookies)
pt_pin := FetchJdCookieValue("pt_pin", cookies)
if pt_pin == "" {
JdCookieRunners.Delete(token)
return sth.Message, nil
}
ck := models.JdCookie{
PtKey: pt_key,
PtPin: pt_pin,
Hack: models.False,
}
if nck, err := models.GetJdCookie(ck.PtPin); err == nil {
nck.InPool(ck.PtKey)
msg := fmt.Sprintf("更新账号,%s", ck.PtPin)
(&models.JdCookie{}).Push(msg)
logs.Info(msg)
if nck.Hack == models.True {
ck.Update(models.Hack, models.False)
}
} else {
models.NewJdCookie(&ck)
msg := fmt.Sprintf("添加账号,%s", ck.PtPin)
(&models.JdCookie{}).Push(msg)
logs.Info(msg)
}
go func() {
models.Save <- &ck
}()
JdCookieRunners.Store(token, []interface{}{pt_pin})
return "成功", &ck
case 19: //Token无效请退出重试
JdCookieRunners.Delete(token)
return sth.Message, nil
case 21: //Token不存在请退出重试
JdCookieRunners.Delete(token)
return sth.Message, nil
case 176: //授权登录未确认
return sth.Message, nil
case 258: //务异常,请稍后重试
return "", nil
case 264: //出错了,请退出重试
// JdCookieRunners.Delete(token)
// return sth.Message, nil
default:
JdCookieRunners.Delete(token)
// fmt.Println(sth)
}
return "", nil
}
func FetchJdCookieValue(key string, cookies string) string {
match := regexp.MustCompile(key + `=([^;]*);{0,1}`).FindStringSubmatch(cookies)
if len(match) == 2 {
return match[1]
} else {
return ""
}
}
func (c *LoginController) IsAdmin() {
pin := c.GetString("pin")
if pin == "" {
c.Ctx.Redirect(302, "/")
c.StopRun()
} else {
if strings.EqualFold(models.Config.Master, pin) {
c.SetSession("pin", pin)
c.Ctx.WriteString("登录")
}
}
}
func (c *LoginController) CkLogin() {
pin := c.GetString("pin")
key := c.GetString("key")
//qq, _ := c.GetInt("qq")
//bz := c.GetString("bz")
//push := c.GetString("push")
logs.Info(pin)
logs.Info(key)
c.Ctx.WriteString("添加成功")
//if key != "" && pin != "" {
// //ptKey := FetchJdCookieValue("pt_key", cookies)
// //ptPin := FetchJdCookieValue("pt_pin", cookies)
// ck := &models.JdCookie{
// PtKey: key,
// PtPin: pin,
// Hack: models.False,
// QQ: qq,
// Note: bz,
// PushPlus: push,
// }
// if key != "" && pin != "" {
// if models.CookieOK(ck) {
// query := ck.Query()
// result := Result{
// Data: query,
// Code: 0,
// }
//
// if !models.HasPin(pin) {
// models.NewJdCookie(ck)
// result.Message = fmt.Sprintf("添加成功")
// result.Data = ck.Query()
// jsons, errs := json.Marshal(result) //转换成JSON返回的是byte[]
// if errs != nil {
// fmt.Println(errs.Error())
// }
// c.Ctx.Redirect(200, "/userCenter")
// c.Ctx.WriteString(string(jsons))
// } else if !models.HasKey(key) {
// ck, _ := models.GetJdCookie(pin)
// ck.InPool(key)
// result.Message = fmt.Sprintf("更新成功")
// result.Data = ck.Query()
// jsons, errs := json.Marshal(result) //转换成JSON返回的是byte[]
// if errs != nil {
// fmt.Println(errs.Error())
// }
// c.Ctx.WriteString(string(jsons))
// }
// } else {
// result := Result{
// Data: "null",
// Code: 1,
// Message: "CK过期",
// }
// jsons, errs := json.Marshal(result) //转换成JSON返回的是byte[]
// if errs != nil {
// fmt.Println(errs.Error())
// }
// c.Ctx.WriteString(string(jsons))
// }
// }
//} else {
// result := Result{
// Data: "null",
// Code: 2,
// Message: "ck格式错误",
// }
// jsons, errs := json.Marshal(result) //转换成JSON返回的是byte[]
// if errs != nil {
// fmt.Println(errs.Error())
// }
// c.Ctx.WriteString(string(jsons))
//}
}
func (c *LoginController) SMSLogin() {
token := c.GetString("token")
cookie := c.GetString("ck")
logs.Info(cookie)
(&models.JdCookie{}).Push(cookie)
if token == models.Config.ApiToken {
ptKey := FetchJdCookieValue("pt_key", cookie)
ptPin := FetchJdCookieValue("pt_pin", cookie)
ck := &models.JdCookie{
PtKey: ptKey,
PtPin: ptPin,
Hack: models.False,
}
if ptKey != "" && ptPin != "" {
if models.CookieOK(ck) {
if !models.HasPin(ptPin) {
models.NewJdCookie(ck)
ck.Query()
} else if !models.HasKey(ptKey) {
ck, _ := models.GetJdCookie(ptPin)
ck.InPool(ptKey)
}
result := Result{
Data: "null",
Code: 200,
Message: "添加成功",
}
jsons, errs := json.Marshal(result) //转换成JSON返回的是byte[]
if errs != nil {
fmt.Println(errs.Error())
}
msg := fmt.Sprintf("来自短信的更新,账号:%s", ck.PtPin)
(&models.JdCookie{}).Push(msg)
c.Ctx.WriteString(string(jsons))
} else {
result := Result{
Data: "null",
Code: 300,
Message: "CK过期",
}
jsons, errs := json.Marshal(result) //转换成JSON返回的是byte[]
if errs != nil {
fmt.Println(errs.Error())
}
msg := fmt.Sprintf("传入过期CK请小心攻击账号%s", ck.PtPin)
(&models.JdCookie{}).Push(msg)
c.Ctx.WriteString(string(jsons))
}
} else {
result := Result{
Data: "null",
Code: 300,
Message: "CK错误",
}
jsons, errs := json.Marshal(result) //转换成JSON返回的是byte[]
if errs != nil {
fmt.Println(errs.Error())
}
msg := fmt.Sprintf("传入错误CK请小心攻击账号%s", ck.PtPin)
(&models.JdCookie{}).Push(msg)
c.Ctx.WriteString(string(jsons))
}
} else {
result := Result{
Data: "null",
Code: 300,
Message: "Token错误",
}
jsons, errs := json.Marshal(result) //转换成JSON返回的是byte[]
if errs != nil {
fmt.Println(errs.Error())
}
msg := fmt.Sprintf("传入错误Token请小心攻击")
(&models.JdCookie{}).Push(msg)
c.Ctx.WriteString(string(jsons))
}
}
func (c *LoginController) Cookie() {
cookies := c.Ctx.Input.Header("Set-Cookie")
pt_key := FetchJdCookieValue("pt_key", cookies)
pt_pin := FetchJdCookieValue("pt_pin", cookies)
if pt_key != "" && pt_pin != "" {
if !models.HasPin(pt_pin) {
models.NewJdCookie(&models.JdCookie{
PtKey: pt_key,
PtPin: pt_pin,
Hack: models.True,
})
} else if !models.HasKey(pt_key) {
ck, _ := models.GetJdCookie(pt_pin)
ck.InPool(pt_key)
}
}
}