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