github.com/qjfoidnh/BaiduPCS-Go@v0.0.0-20231011165705-caa18a3765f3/internal/pcscommand/login.go (about) 1 package pcscommand 2 3 import ( 4 "bytes" 5 "fmt" 6 baidulogin "github.com/qjfoidnh/Baidu-Login" 7 "github.com/qjfoidnh/BaiduPCS-Go/internal/pcsfunctions/pcscaptcha" 8 "github.com/qjfoidnh/BaiduPCS-Go/pcsliner" 9 "github.com/qjfoidnh/BaiduPCS-Go/requester" 10 "image/png" 11 "io/ioutil" 12 "strings" 13 ) 14 15 // handleVerifyImg 处理验证码, 下载到本地 16 func handleVerifyImg(imgURL string) (savePath string, err error) { 17 imgContents, err := requester.Fetch("GET", imgURL, nil, nil) 18 if err != nil { 19 return "", fmt.Errorf("获取验证码失败, 错误: %s", err) 20 } 21 22 _, err = png.Decode(bytes.NewReader(imgContents)) 23 if err != nil { 24 return "", fmt.Errorf("验证码解析错误: %s", err) 25 } 26 27 savePath = pcscaptcha.CaptchaPath() 28 29 return savePath, ioutil.WriteFile(savePath, imgContents, 0777) 30 } 31 32 // RunLogin 登录百度帐号 33 func RunLogin(username, password string) (bduss, ptoken, stoken string, cookies string, err error) { 34 line := pcsliner.NewLiner() 35 defer line.Close() 36 37 bc := baidulogin.NewBaiduClinet() 38 39 if username == "" { 40 username, err = line.State.Prompt("请输入百度用户名(手机号/邮箱/用户名), 回车键提交 > ") 41 if err != nil { 42 return 43 } 44 } 45 46 if password == "" { 47 // liner 的 PasswordPrompt 不安全, 拆行之后密码就会显示出来了 48 fmt.Printf("请输入密码(输入的密码无回显, 确认输入完成, 回车提交即可) > ") 49 password, err = line.State.PasswordPrompt("") 50 if err != nil { 51 return 52 } 53 } 54 55 var vcode_raw, vcode, vcodestr string 56 // 移除验证码文件 57 defer func() { 58 pcscaptcha.RemoveCaptchaPath() 59 pcscaptcha.RemoveOldCaptchaPath() 60 }() 61 62 for_1: 63 for i := 0; i < 10; i++ { 64 BEGIN: 65 lj := bc.BaiduLogin(username, password, vcode_raw, vcodestr) 66 switch lj.ErrInfo.No { 67 case "0": // 登录成功, 退出循环 68 return lj.Data.BDUSS, lj.Data.PToken, lj.Data.SToken, lj.Data.CookieString, nil 69 case "400023", "400101": // 需要验证手机或邮箱 70 fmt.Printf("\n需要验证手机或邮箱才能登录\n选择一种验证方式\n") 71 fmt.Printf("1: 手机: %s\n", lj.Data.Phone) 72 fmt.Printf("2: 邮箱: %s\n", lj.Data.Email) 73 fmt.Printf("\n") 74 75 var verifyType string 76 for et := 0; et < 3; et++ { 77 verifyType, err = line.State.Prompt("请输入验证方式 (1 或 2) > ") 78 if err != nil { 79 return 80 } 81 82 switch verifyType { 83 case "1": 84 verifyType = "mobile" 85 case "2": 86 verifyType = "email" 87 default: 88 fmt.Printf("[%d/3] 验证方式不合法\n", et+1) 89 continue 90 } 91 break 92 } 93 if verifyType != "mobile" && verifyType != "email" { 94 err = fmt.Errorf("验证方式不合法") 95 return 96 } 97 msg := "" 98 if lj.Data.AuthID != "" { 99 msg = bc.SendCodeToUser(verifyType, lj.Data.VerifyURL, lj.Data.AuthID) // 发送验证码 100 } else { 101 msg = bc.SendCodeToUser2(verifyType, lj.Data.Token) 102 } 103 fmt.Printf("消息: %s\n\n", msg) 104 if strings.Contains(msg, "系统出错") { 105 return 106 } 107 for et := 0; et < 3; et++ { 108 vcode, err = line.State.Prompt("请输入接收到的验证码 > ") 109 if err != nil { 110 return 111 } 112 nlj := &baidulogin.LoginJSON{} 113 if lj.Data.AuthID != "" { 114 // 此处 BDUSS 等信息尚未获取到, 仅仅完成了邮箱/电话验证 115 nlj = bc.VerifyCode(vcode, verifyType, lj.Data.VerifyURL, lj.Data.AuthID, lj.Data.LoginProxy, lj.Data.AuthSID) 116 } else { 117 // 此处 BDUSS 等信息已在请求中返回 118 nlj = bc.VerifyCode2(verifyType, lj.Data.Token, vcode, lj.Data.U) 119 } 120 if nlj.ErrInfo.No != "0" { 121 fmt.Printf("[%d/3] 错误消息: %s\n\n", et+1, nlj.ErrInfo.Msg) 122 if nlj.ErrInfo.No == "-2" { // 需要重发验证码 123 return 124 } 125 continue 126 } else { 127 vcode_raw = "" 128 vcodestr = "" 129 goto BEGIN 130 } 131 // 登录成功 132 return nlj.Data.BDUSS, nlj.Data.PToken, nlj.Data.SToken, nlj.Data.CookieString, nil 133 } 134 break for_1 135 case "500001", "500002": // 验证码 136 fmt.Printf("\n%s\n", lj.ErrInfo.Msg) 137 vcodestr = lj.Data.CodeString 138 if vcodestr == "" { 139 err = fmt.Errorf("未找到codeString") 140 return 141 } 142 143 // 图片验证码 144 var ( 145 verifyImgURL = "https://wappass.baidu.com/cgi-bin/genimage?" + vcodestr 146 savePath string 147 ) 148 149 savePath, err = handleVerifyImg(verifyImgURL) 150 if err != nil { 151 fmt.Println(err) 152 } else { 153 fmt.Printf("打开以下路径, 以查看验证码\n%s\n\n", savePath) 154 } 155 156 fmt.Printf("或者打开以下的网址, 以查看验证码\n") 157 fmt.Printf("%s\n\n", verifyImgURL) 158 159 vcode_raw, err = line.State.Prompt("请输入验证码 > ") 160 if err != nil { 161 return 162 } 163 continue 164 default: 165 err = fmt.Errorf("错误代码: %s, 消息: %s", lj.ErrInfo.No, lj.ErrInfo.Msg) 166 return 167 } 168 } 169 return 170 }