├── .gitignore ├── .idea └── vcs.xml ├── README.md ├── 京东2018-12-13 ├── js.txt └── login.py ├── 京东登陆 ├── js.txt └── login.py ├── 微信公众号登陆加密 ├── js.txt └── login.py ├── 新浪微博登陆2018-12-11 ├── js.txt └── sinalogin.py ├── 网易云评论请求加密2018-12-12 ├── js.txt └── wangyicomment.py ├── 腾讯企鹅媒体登陆2018-12-8 ├── js.txt └── login-om.qq.com.py └── 英领 ├── .idea ├── misc.xml ├── modules.xml ├── workspace.xml └── 英领.iml └── linkedin.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python-Crypto 2 | 记录平时做js加密解密算法 3 | --- 4 | ## 新浪微博登陆 5 | 测试的是手机号可以正常登陆,还没遇到验证码问题,后面遇上再加
6 | post请求之后会被重定向两次才能得到登陆用户信息,发送post请求后还需要正则匹配两次重定向url
7 | 注意请求返回的编码格式post请求后返回编码是GBK,后面还会返回GB2312 8 | ### 加密方式:RSA(非对称加密方式) 9 | 登录前先get请求返回携带有token、pubkey、raskv、servertime等信息的dict字符串,包含在js中需要提取转换 10 | 需要破解的参数是su和sp,sp是密码
11 | su:是通过封装了RSA源码的一个对象sinaSSOEncoder的base64编码用户名得到的
12 | sp:加密的密码,通过创建sinaSSOEncoder加密对象,公钥是上面返回的pubkey,偏移量"10001" 13 | 加密内容是servertime + "\t" + nonce + "\n" + pw 14 | servertime:上面get请求返回的 15 | nonce:上面get请求返回的 16 | pw:输入的密码 17 | ## 腾讯企鹅媒体 18 | 测试的是邮箱登陆,无验证码问题,因为账号问题可能在登陆后被重定向到身份验证页面 19 | 注意在post请求时需要带上cookie,并且cookie中有个参数是登录前Ajax get请求的含有token信息的返回cookie 20 | ### 加密方式:MD5双重加密(信息摘要算法或签名算法) 21 | 登录前后台会get请求一次,返回含有token和salf等加密参数信息以及一个cookie,该cookie要加在post的请求中 22 | 加密形式:MD5(token + MD5(salt + pwd))双重加密 23 | ## 网易云获取评论请求参数加密 24 | 测试是无登陆状态下的请求加密,无登陆状态下csrf_token参数为空,在同一ip过度请求下降不会返回数据;在登陆状态下请求的url和未登录状态下的url是不一样的 25 | ### 加密方式AES+RSA 26 | 评论请求加密参数是两个:params、encSecKey,传入加密函数的参数是a,b,c,d+内部随机生成的16位参数i 27 | 其中a='"{"rid":"R_SO_4_371362","offset":"160","total":"false","limit":"20","csrf_token":"de097d5986487c4aefe9f52c65e43224"}"}'形式参数 28 | rid:歌曲id; 29 | offset:歌词页数计算公式(n-1)*20; 30 | total:在第一页是TRUE在其他是false; 31 | csrf_token:在登陆成功后再返回的cookie中可以找到,未登录时是空。 32 | b、c、d是固定的参数,由js内部定义的文字编码转码并并且得到的类似于 33 | {"色":"00e0b","流感":"509f6","这边":"259df","弱":"8642d","嘴 唇":"bc356","亲":"62901","开心":"477df"}-->色+嘴唇="00e0bbc356" 34 | bcd当做固定参数传入 35 | 其中内部随便变量i可以写死,那么encSecKey参数都是由固定参数生成的,可以当做固定参数使用 36 | params根据页数和歌曲参数的不同是变化的 37 | params:是内部方法AES CBC模式 38 | encSecKey:RSA加密 39 | ## 微信公众号密码加密 40 | 只分析了微信公众号登陆请求的post密码加密 41 | ### 加密方式MD5 42 | 加密方式比较简单,取密码的前16位进行MD5加密 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /京东2018-12-13/login.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import execjs 3 | from lxml import etree 4 | 5 | URL = "https://passport.jd.com/new/login.aspx?ReturnUrl=https%3A%2F%2Fwww.jd.com%2F%3Fcu%3Dtrue%26utm_source%3Dbaidu" \ 6 | "-pinzhuan%26utm_medium%3Dcpc%26utm_campaign%3Dt_288551095_baidupinzhuan%26utm_term%3D0f3d30c8dba7459bb52f2eb5eb" \ 7 | "a8ac7d_0_b4ece126b50f487280968f8ddba60aa8" 8 | 9 | session = requests.Session() 10 | with open("./js.txt", 'r', encoding='utf-8') as f: # 打开JS文件 11 | line = f.readline() 12 | htmlstr = '' 13 | while line: 14 | htmlstr = htmlstr + line 15 | line = f.readline() 16 | jsstr = htmlstr 17 | ctx = execjs.compile(jsstr) # 加载JS文件 18 | 19 | 20 | def getform(phone, pwd): 21 | response = session.get(URL) 22 | rp = etree.HTML(response.text) 23 | sa_token = rp.xpath('//input[@id="sa_token"]/@value')[0] 24 | uuid = rp.xpath('//input[@id="uuid"]/@value')[0] 25 | eid = rp.xpath('//input[@id="eid"]/@value')[0] 26 | sessionId = rp.xpath('//input[@id="sessionId"]/@value')[0] 27 | token = rp.xpath('//input[@id="token"]/@value')[0] 28 | loginType = rp.xpath('//input[@id="loginType"]/@value')[0] 29 | pubKey = rp.xpath('//input[@id="pubKey"]/@value')[0] 30 | slideAppId = rp.xpath('//input[@id="slideAppId"]/@value')[0] 31 | useSlideAuthCode = rp.xpath('//input[@id="useSlideAuthCode"]/@value')[0] 32 | loginname = phone 33 | pwd = ctx.call("getEntryptPwd", pubKey, pwd) 34 | seqSid = "271726271731661547" 35 | authcode = None # 服务器返回的时间戳,还需单独请求 36 | data = { 37 | "uuid": uuid, 38 | "eid": eid, 39 | "fp": sessionId, 40 | "_t": token, 41 | "loginType": loginType, 42 | "loginname": loginname, 43 | "nloginpwd": pwd, 44 | "authcode": authcode, 45 | "pubKey": pubKey, 46 | "sa_token": sa_token, 47 | "seqSid": seqSid, 48 | "useSlideAuthCode": useSlideAuthCode 49 | } 50 | return data 51 | 52 | 53 | if __name__ == '__main__': 54 | getform(18328496803, 666666) -------------------------------------------------------------------------------- /京东登陆/login.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import execjs 3 | from lxml import etree 4 | 5 | URL = "https://passport.jd.com/new/login.aspx?ReturnUrl=https%3A%2F%2Fwww.jd.com%2F%3Fcu%3Dtrue%26utm_source%3Dbaidu" \ 6 | "-pinzhuan%26utm_medium%3Dcpc%26utm_campaign%3Dt_288551095_baidupinzhuan%26utm_term%3D0f3d30c8dba7459bb52f2eb5eb" \ 7 | "a8ac7d_0_b4ece126b50f487280968f8ddba60aa8" 8 | 9 | session = requests.Session() 10 | with open("./js.txt", 'r', encoding='utf-8') as f: # 打开JS文件 11 | line = f.readline() 12 | htmlstr = '' 13 | while line: 14 | htmlstr = htmlstr + line 15 | line = f.readline() 16 | jsstr = htmlstr 17 | ctx = execjs.compile(jsstr) # 加载JS文件 18 | 19 | 20 | def getform(phone, pwd): 21 | response = session.get(URL) 22 | rp = etree.HTML(response.text) 23 | sa_token = rp.xpath('//input[@id="sa_token"]/@value')[0] 24 | uuid = rp.xpath('//input[@id="uuid"]/@value')[0] 25 | eid = rp.xpath('//input[@id="eid"]/@value')[0] 26 | sessionId = rp.xpath('//input[@id="sessionId"]/@value')[0] 27 | token = rp.xpath('//input[@id="token"]/@value')[0] 28 | loginType = rp.xpath('//input[@id="loginType"]/@value')[0] 29 | pubKey = rp.xpath('//input[@id="pubKey"]/@value')[0] 30 | slideAppId = rp.xpath('//input[@id="slideAppId"]/@value')[0] 31 | useSlideAuthCode = rp.xpath('//input[@id="useSlideAuthCode"]/@value')[0] 32 | loginname = phone 33 | pwd = ctx.call("getEntryptPwd", pubKey, pwd) 34 | seqSid = "271726271731661547" 35 | authcode = None # 服务器返回的时间戳,还需单独请求 36 | data = { 37 | "uuid": uuid, 38 | "eid": eid, 39 | "fp": sessionId, 40 | "_t": token, 41 | "loginType": loginType, 42 | "loginname": loginname, 43 | "nloginpwd": pwd, 44 | "authcode": authcode, 45 | "pubKey": pubKey, 46 | "sa_token": sa_token, 47 | "seqSid": seqSid, 48 | "useSlideAuthCode": useSlideAuthCode 49 | } 50 | return data 51 | 52 | 53 | if __name__ == '__main__': 54 | getform(18328496803, 666666) -------------------------------------------------------------------------------- /微信公众号登陆加密/js.txt: -------------------------------------------------------------------------------- 1 | function e(n, r) { 2 | var t = (65535 & n) + (65535 & r); 3 | return (n >> 16) + (r >> 16) + (t >> 16) << 16 | 65535 & t 4 | } 5 | function u(n, r, t, u, o, c) { 6 | return e(function(n, r) { 7 | return n << r | n >>> 32 - r 8 | } (e(e(r, n), e(u, c)), o), t) 9 | } 10 | function o(n, r, t, e, o, c, f) { 11 | return u(r & t | ~r & e, n, r, o, c, f) 12 | } 13 | function c(n, r, t, e, o, c, f) { 14 | return u(r & e | t & ~e, n, r, o, c, f) 15 | } 16 | function f(n, r, t, e, o, c, f) { 17 | return u(r ^ t ^ e, n, r, o, c, f) 18 | } 19 | function i(n, r, t, e, o, c, f) { 20 | return u(t ^ (r | ~e), n, r, o, c, f) 21 | } 22 | function a(n, r) { 23 | n[r >> 5] |= 128 << r % 32, 24 | n[14 + (r + 64 >>> 9 << 4)] = r 25 | var t, u, a, h, d, g = 1732584193, 26 | l = -271733879, 27 | v = -1732584194, 28 | s = 271733878 29 | for (t = 0; t < n.length; t += 16) u = g, 30 | a = l, 31 | h = v, 32 | d = s, 33 | l = i(l = i(l = i(l = i(l = f(l = f(l = f(l = f(l = c(l = c(l = c(l = c(l = o(l = o(l = o(l = o(l, v = o(v, s = o(s, g = o(g, l, v, s, n[t], 7, -680876936), l, v, n[t + 1], 12, -389564586), g, l, n[t + 2], 17, 606105819), s, g, n[t + 3], 22, -1044525330), v = o(v, s = o(s, g = o(g, l, v, s, n[t + 4], 7, -176418897), l, v, n[t + 5], 12, 1200080426), g, l, n[t + 6], 17, -1473231341), s, g, n[t + 7], 22, -45705983), v = o(v, s = o(s, g = o(g, l, v, s, n[t + 8], 7, 1770035416), l, v, n[t + 9], 12, -1958414417), g, l, n[t + 10], 17, -42063), s, g, n[t + 11], 22, -1990404162), v = o(v, s = o(s, g = o(g, l, v, s, n[t + 12], 7, 1804603682), l, v, n[t + 13], 12, -40341101), g, l, n[t + 14], 17, -1502002290), s, g, n[t + 15], 22, 1236535329), v = c(v, s = c(s, g = c(g, l, v, s, n[t + 1], 5, -165796510), l, v, n[t + 6], 9, -1069501632), g, l, n[t + 11], 14, 643717713), s, g, n[t], 20, -373897302), v = c(v, s = c(s, g = c(g, l, v, s, n[t + 5], 5, -701558691), l, v, n[t + 10], 9, 38016083), g, l, n[t + 15], 14, -660478335), s, g, n[t + 4], 20, -405537848), v = c(v, s = c(s, g = c(g, l, v, s, n[t + 9], 5, 568446438), l, v, n[t + 14], 9, -1019803690), g, l, n[t + 3], 14, -187363961), s, g, n[t + 8], 20, 1163531501), v = c(v, s = c(s, g = c(g, l, v, s, n[t + 13], 5, -1444681467), l, v, n[t + 2], 9, -51403784), g, l, n[t + 7], 14, 1735328473), s, g, n[t + 12], 20, -1926607734), v = f(v, s = f(s, g = f(g, l, v, s, n[t + 5], 4, -378558), l, v, n[t + 8], 11, -2022574463), g, l, n[t + 11], 16, 1839030562), s, g, n[t + 14], 23, -35309556), v = f(v, s = f(s, g = f(g, l, v, s, n[t + 1], 4, -1530992060), l, v, n[t + 4], 11, 1272893353), g, l, n[t + 7], 16, -155497632), s, g, n[t + 10], 23, -1094730640), v = f(v, s = f(s, g = f(g, l, v, s, n[t + 13], 4, 681279174), l, v, n[t], 11, -358537222), g, l, n[t + 3], 16, -722521979), s, g, n[t + 6], 23, 76029189), v = f(v, s = f(s, g = f(g, l, v, s, n[t + 9], 4, -640364487), l, v, n[t + 12], 11, -421815835), g, l, n[t + 15], 16, 530742520), s, g, n[t + 2], 23, -995338651), v = i(v, s = i(s, g = i(g, l, v, s, n[t], 6, -198630844), l, v, n[t + 7], 10, 1126891415), g, l, n[t + 14], 15, -1416354905), s, g, n[t + 5], 21, -57434055), v = i(v, s = i(s, g = i(g, l, v, s, n[t + 12], 6, 1700485571), l, v, n[t + 3], 10, -1894986606), g, l, n[t + 10], 15, -1051523), s, g, n[t + 1], 21, -2054922799), v = i(v, s = i(s, g = i(g, l, v, s, n[t + 8], 6, 1873313359), l, v, n[t + 15], 10, -30611744), g, l, n[t + 6], 15, -1560198380), s, g, n[t + 13], 21, 1309151649), v = i(v, s = i(s, g = i(g, l, v, s, n[t + 4], 6, -145523070), l, v, n[t + 11], 10, -1120210379), g, l, n[t + 2], 15, 718787259), s, g, n[t + 9], 21, -343485551), 34 | g = e(g, u), 35 | l = e(l, a), 36 | v = e(v, h), 37 | s = e(s, d); 38 | return [g, l, v, s] 39 | } 40 | function h(n) { 41 | var r, t = "" 42 | for (r = 0; r < 32 * n.length; r += 8) t += String.fromCharCode(n[r >> 5] >>> r % 32 & 255) ;return t 43 | } 44 | function d(n) { 45 | var r, t = [] 46 | for (t[(n.length >> 2) - 1] = void 0, r = 0; r < t.length; r += 1) t[r] = 0 47 | for (r = 0; r < 8 * n.length; r += 8) t[r >> 5] |= (255 & n.charCodeAt(r / 8)) << r % 32 48 | return t 49 | } 50 | function g(n) { 51 | var r, t, e = "" 52 | for (t = 0; t < n.length; t += 1) r = n.charCodeAt(t), 53 | e += "0123456789abcdef".charAt(r >>> 4 & 15) + "0123456789abcdef".charAt(15 & r); 54 | return e 55 | } 56 | function l(n) { 57 | return unescape(encodeURIComponent(n)) 58 | } 59 | function v(n) { 60 | return function(n) { 61 | return h(a(d(n), 8 * n.length)) 62 | } (l(n)) 63 | } 64 | function s(n, r) { 65 | return function(n, r) { 66 | var t, e, u = d(n), 67 | o = [], 68 | c = [] 69 | for (o[15] = c[15] = void 0, u.length > 16 && (u = a(u, 8 * n.length)), t = 0; t < 16; t += 1) o[t] = 909522486 ^ u[t], 70 | c[t] = 1549556828 ^ u[t] 71 | return e = a(o.concat(d(r)), 512 + 8 * r.length), 72 | h(a(c.concat(e), 640)) 73 | } (l(n), l(r)) 74 | } 75 | 76 | getpwd = function(n, r, t) { 77 | return r ? t ? s(r, n) : function(n, r) { 78 | return g(s(n, r)) 79 | } (r, n) : t ? v(n) : function(n) { 80 | return g(v(n)) 81 | } (n) 82 | } -------------------------------------------------------------------------------- /微信公众号登陆加密/login.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | import requests 4 | import execjs 5 | 6 | 7 | with open("./js.txt", 'r', encoding='utf-8') as f: # 打开JS文件 8 | line = f.readline() 9 | htmlstr = '' 10 | while line: 11 | htmlstr = htmlstr + line 12 | line = f.readline() 13 | jsstr = htmlstr 14 | ctx = execjs.compile(jsstr) # 加载JS文件 15 | 16 | 17 | def getpwd(pwd): 18 | password = ctx.call("getpwd", pwd) 19 | return password 20 | 21 | 22 | def login(email, pwd): 23 | session = requests.Session() 24 | url = "https://mp.weixin.qq.com/cgi-bin/bizlogin?action=startlogin" 25 | password = getpwd(pwd) 26 | data = { 27 | "username": email, 28 | "pwd": password, 29 | "imgcode": "", 30 | "f": "json", 31 | "userlang": "zh_CN", 32 | "redirect_url": "", 33 | "token": "", 34 | "lang": "zh_CN", 35 | "ajax": "1" 36 | } 37 | rp = session.post(url, data=data) 38 | 39 | 40 | if __name__ == '__main__': 41 | login("2551513277@qq.com", "666666") 42 | 43 | 44 | -------------------------------------------------------------------------------- /新浪微博登陆2018-12-11/js.txt: -------------------------------------------------------------------------------- 1 | var navigator = {}; 2 | function SSOController() { 3 | var undefined; 4 | var me = this; 5 | var updateCookieTimer = null; 6 | var updateCookieTimeHardLimit = 1800; 7 | var cookieExpireTimeLength = 3600 * 24; 8 | var crossDomainForward = null; 9 | var crossDomainTimer = null; 10 | var crossDomainTime = 3; 11 | var autoLoginCallBack2 = null; 12 | var ssoCrosssDomainUrl = "http://login.sina.com.cn/sso/crossdomain.php"; 13 | var ssoLoginUrl = "http://login.sina.com.cn/sso/login.php"; 14 | var ssoLogoutUrl = "http://login.sina.com.cn/sso/logout.php"; 15 | var ssoUpdateCookieUrl = "http://login.sina.com.cn/sso/updatetgt.php"; 16 | var ssoPreLoginUrl = "http://login.sina.com.cn/sso/prelogin.php"; 17 | var pincodeUrl = "http://login.sina.com.cn/cgi/pin.php"; 18 | var vfValidUrl = "http://weibo.com/sguide/vdun.php"; 19 | var generateVisitorUrl = "http://passport.weibo.com/visitor/visitor"; 20 | var crossDomainUrlList = null; 21 | var loginMethod = ""; 22 | var ssoServerTimeTimer = null; 23 | var ssoLoginTimer = null; 24 | var loginByConfig = null; 25 | var loginMethodCheck = null; 26 | var https = 1; 27 | var rsa = 2; 28 | var wsse = 4; 29 | var pcid = ""; 30 | var tmpData = {}; 31 | var preloginTimeStart = 0; 32 | var preloginTime = 0; 33 | var callbackLogoutStatus; 34 | this.https = 1; 35 | this.rsa = 2; 36 | this.wsse = 4; 37 | this.name = "sinaSSOController"; 38 | this.loginFormId = "ssoLoginForm"; 39 | this.scriptId = "ssoLoginScript"; 40 | this.ssoCrossDomainScriptId = "ssoCrossDomainScriptId"; 41 | this.loginFrameName = "ssoLoginFrame"; 42 | this.appLoginURL = { 43 | "weibo.com": "https://passport.weibo.com/wbsso/login" 44 | }; 45 | this.appDomainService = { 46 | "weibo.com": "miniblog" 47 | }; 48 | this.loginExtraQuery = {}; 49 | this.setDomain = false; 50 | this.feedBackUrl = ""; 51 | this.service = "sso"; 52 | this.domain = "sina.com.cn"; 53 | this.from = ""; 54 | this.pageCharset = "GB2312"; 55 | this.useTicket = false; 56 | this.isCheckLoginState = false; 57 | this.isUpdateCookieOnLoad = true; 58 | this.useIframe = true; 59 | this.noActiveTime = 7200; 60 | this.autoUpdateCookieTime = 1800; 61 | this.loginType = rsa; 62 | this.timeoutEnable = false; 63 | this.loginTimeout = 5000; 64 | this.crossDomain = true; 65 | this.scriptLoginHttps = false; 66 | this.allowAutoFoundServerTime = false; 67 | this.allowAutoFoundServerTimeError = true; 68 | this.calcServerTimeInterval = 2000; 69 | this.servertime = null; 70 | this.nonce = null; 71 | this.rsaPubkey = null; 72 | this.rsakv = null; 73 | this.loginExtraFlag = {}; 74 | this.cdult = false; 75 | this.crossDomainTime = 5; 76 | this.failRedirect = false; 77 | this.isGenerateVisitor = true; 78 | this.generateVisitorProbability = 1; 79 | this.generateVisitorDelay = 6; 80 | this.generateVisitorDomain = ["^.*sina.com.cn$"]; 81 | this.getVersion = function() { 82 | return "ssologin.js(v1.4.18) 2014-06-12" 83 | }; 84 | this.getEntry = function() { 85 | return me.entry 86 | }; 87 | this.getClientType = function() { 88 | return me.getVersion().split(" ")[0] 89 | }; 90 | this.init = function() { 91 | if (getType(arguments[0]) === "object") { 92 | return customPrepare(arguments[0]) 93 | } 94 | me.setLoginType(me.loginType); 95 | var ssoConfig = window.sinaSSOConfig; 96 | if (typeof ssoConfig != "object") { 97 | ssoConfig = {} 98 | } 99 | var name; 100 | for (name in ssoConfig) { 101 | me[name] = ssoConfig[name] 102 | } 103 | if (!me.entry) { 104 | me.entry = me.service 105 | } 106 | if (me.isUpdateCookieOnLoad) { 107 | setTimeout(me.name + ".updateCookie()", 10000) 108 | } 109 | if (me.isGenerateVisitor) { 110 | if (self === top && Math.random() < me.generateVisitorProbability && location.protocol !== "https:") { 111 | setTimeout(me.name + ".generateVisitor()", me.generateVisitorDelay * 1000) 112 | } 113 | } 114 | if (me.isCheckLoginState) { 115 | addEventListener(window, "load", 116 | function() { 117 | me.checkLoginState() 118 | }) 119 | } 120 | if (me.allowAutoFoundServerTime && ssoLoginServerTime) { 121 | me.setServerTime(ssoLoginServerTime) 122 | } 123 | me.customInit() 124 | }; 125 | this.getLoginInfo = function() { 126 | var sso_info = getCookie("sso_info"); 127 | if (!sso_info) { 128 | return {} 129 | } 130 | try { 131 | return parse_str(sinaSSOEncoder.Cookie.decode(sso_info)) 132 | } catch(e) { 133 | return {} 134 | } 135 | }; 136 | this.customInit = function() {}; 137 | this.customUpdateCookieCallBack = function(result) {}; 138 | this.customLoginCallBack = function(loginStatus) {}; 139 | this.customLogoutCallBack = function(result) { 140 | me.customLoginCallBack({ 141 | result: false 142 | }) 143 | }; 144 | var customLogin, customPrepare, customLogout; (function() { 145 | var $empty = function() {}, 146 | loginParam = { 147 | username: "", 148 | password: "", 149 | savestate: 0, 150 | vsnf: 0, 151 | vsnval: "", 152 | door: "", 153 | setCookie: 1, 154 | ssoSimpleLogin: 0, 155 | onComplete: $empty, 156 | onSuccess: $empty, 157 | onFailure: $empty 158 | }, 159 | logoutParam = { 160 | onComplete: $empty, 161 | onSuccess: $empty, 162 | onFailure: $empty 163 | }, 164 | hashExtra = { 165 | vsnf: "vsnf", 166 | vsnval: "vsnval", 167 | door: "door", 168 | setCookie: "s", 169 | ssoSimpleLogin: "ssosimplelogin" 170 | }, 171 | loginOptions = {}, 172 | logoutOptions = {}; 173 | var parseParam = function(original, spec) { 174 | var key, param = {}; 175 | original = original || {}; 176 | spec = spec || {}; 177 | objMerge(param, original); 178 | for (key in spec) { 179 | if (original.hasOwnProperty(key)) { 180 | param[key] = spec[key] 181 | } 182 | } 183 | return param 184 | }; 185 | var callback = function(options, name, loginStatus) { 186 | if (typeof(options[name]) === "function") { 187 | options[name](loginStatus) 188 | } 189 | }; 190 | this.callbackLoginStatus = function(loginStatus) { 191 | me.customLoginCallBack(loginStatus); 192 | callback(loginOptions, "onComplete", loginStatus); 193 | if (loginStatus && loginStatus.result === true) { 194 | callback(loginOptions, "onSuccess", loginStatus) 195 | } else { 196 | callback(loginOptions, "onFailure", loginStatus) 197 | } 198 | }; 199 | callbackLogoutStatus = function(logoutStatus) { 200 | me.customLogoutCallBack(logoutStatus); 201 | callback(logoutOptions, "onComplete", logoutStatus); 202 | if (logoutStatus && logoutStatus.result === true) { 203 | callback(logoutOptions, "onSuccess", logoutStatus) 204 | } else { 205 | callback(logoutOptions, "onFailure", logoutStatus) 206 | } 207 | }; 208 | customPrepare = function(spec) { 209 | var key; 210 | spec = spec || {}; 211 | loginOptions = objMerge({ 212 | entry: "sso", 213 | useTicket: false, 214 | service: "sso", 215 | domain: "sina.com.cn", 216 | feedBackUrl: "", 217 | setDomain: false, 218 | crossDomain: true, 219 | name: "sinaSSOController" 220 | }, 221 | loginParam); 222 | loginOptions = parseParam(loginOptions, spec); 223 | window[loginOptions.name] = window[loginOptions.name] || me; 224 | for (key in loginOptions) { 225 | if (!loginParam.hasOwnProperty(key)) { 226 | me[key] = loginOptions[key] 227 | } 228 | } 229 | me.loginExtraQuery = {}; 230 | objMerge(me.loginExtraQuery, loginOptions.loginExtraQuery); 231 | for (key in hashExtra) { 232 | if (loginOptions.hasOwnProperty(key)) { 233 | me.loginExtraQuery[hashExtra[key]] = loginOptions[key] 234 | } 235 | } 236 | }; 237 | customLogin = function(spec) { 238 | spec = spec || {}; 239 | customPrepare(spec); 240 | me.login(loginOptions.username, loginOptions.password, loginOptions.savestate) 241 | }; 242 | customLogout = function(spec) { 243 | spec = spec || {}; 244 | logoutOptions = objMerge({}, 245 | logoutParam); 246 | logoutOptions = parseParam(logoutOptions, spec); 247 | me.logout() 248 | } 249 | }).apply(this); 250 | this.login = function(username, password, savestate) { 251 | if (getType(arguments[0]) === "object") { 252 | return customLogin(arguments[0]) 253 | } 254 | if (!ssoLoginTimer) { 255 | ssoLoginTimer = new prototypeTimer(me.timeoutEnable) 256 | } else { 257 | ssoLoginTimer.clear() 258 | } 259 | ssoLoginTimer.start(me.loginTimeout, 260 | function() { 261 | ssoLoginTimer.clear(); 262 | me.callbackLoginStatus({ 263 | result: false, 264 | errno: -1, 265 | reason: unescape("%u767B%u5F55%u8D85%u65F6%uFF0C%u8BF7%u91CD%u8BD5") 266 | }) 267 | }); 268 | savestate = savestate == undefined ? 0 : savestate; 269 | tmpData.savestate = savestate; 270 | loginByConfig = function() { 271 | if (!me.feedBackUrl && loginByXMLHttpRequest(username, password, savestate)) { 272 | return true 273 | } 274 | if (me.useIframe && (me.setDomain || me.feedBackUrl)) { 275 | if (me.setDomain) { 276 | document.domain = me.domain; 277 | if (!me.feedBackUrl && me.domain != "sina.com.cn") { 278 | me.feedBackUrl = makeURL(me.appLoginURL[me.domain], { 279 | domain: 1 280 | }) 281 | } 282 | } 283 | loginMethod = "post"; 284 | var result = loginByIframe(username, password, savestate); 285 | if (!result) { 286 | loginMethod = "get"; 287 | if (me.scriptLoginHttps) { 288 | me.setLoginType(me.loginType | https) 289 | } else { 290 | me.setLoginType(me.loginType | rsa) 291 | } 292 | loginByScript(username, password, savestate) 293 | } 294 | } else { 295 | loginMethod = "get"; 296 | loginByScript(username, password, savestate) 297 | } 298 | me.nonce = null 299 | }; 300 | loginMethodCheck = function() { 301 | if ((me.loginType & wsse) || (me.loginType & rsa)) { 302 | if (me.servertime) { 303 | if (!me.nonce) { 304 | me.nonce = makeNonce(6) 305 | } 306 | loginByConfig(); 307 | return true 308 | } 309 | me.getServerTime(username, loginByConfig) 310 | } else { 311 | loginByConfig() 312 | } 313 | }; 314 | loginMethodCheck(); 315 | return true 316 | }; 317 | this.prelogin = function(config, callback) { 318 | var url = location.protocol == "https:" ? ssoPreLoginUrl.replace(/^http:/, "https:") : ssoPreLoginUrl; 319 | var username = config.username || ""; 320 | username = sinaSSOEncoder.base64.encode(urlencode(username)); 321 | delete config.username; 322 | var arrQuery = { 323 | entry: me.entry, 324 | callback: me.name + ".preloginCallBack", 325 | su: username, 326 | rsakt: "mod" 327 | }; 328 | url = makeURL(url, objMerge(arrQuery, config)); 329 | me.preloginCallBack = function(result) { 330 | if (result && result.retcode == 0) { 331 | me.setServerTime(result.servertime); 332 | me.nonce = result.nonce; 333 | me.rsaPubkey = result.pubkey; 334 | me.rsakv = result.rsakv; 335 | pcid = result.pcid; 336 | preloginTime = (new Date()).getTime() - preloginTimeStart - (parseInt(result.exectime, 10) || 0) 337 | } 338 | if (typeof callback == "function") { 339 | callback(result) 340 | } 341 | }; 342 | preloginTimeStart = (new Date()).getTime(); 343 | excuteScript(me.scriptId, url) 344 | }; 345 | this.getServerTime = function(username, callback) { 346 | if (me.servertime) { 347 | if (typeof callback == "function") { 348 | callback({ 349 | retcode: 0, 350 | servertime: me.servertime 351 | }) 352 | } 353 | return true 354 | } 355 | me.prelogin({ 356 | username: username 357 | }, 358 | callback) 359 | }; 360 | this.logout = function() { 361 | try { 362 | if (getType(arguments[0]) === "object") { 363 | return customLogout(arguments[0]) 364 | } 365 | var request = { 366 | entry: me.getEntry(), 367 | callback: me.name + ".ssoLogoutCallBack" 368 | }; 369 | try { 370 | request.sr = window.screen.width + "*" + window.screen.height 371 | } catch(e) {} 372 | var url = location.protocol == "https:" ? ssoLogoutUrl.replace(/^http:/, "https:") : ssoLogoutUrl; 373 | url = makeURL(url, request); 374 | excuteScript(me.scriptId, url) 375 | } catch(e) {} 376 | return true 377 | }; 378 | this.ssoLogoutCallBack = function(result) { 379 | if (result.arrURL) { 380 | me.setCrossDomainUrlList(result) 381 | } 382 | me.crossDomainAction("logout", 383 | function() { 384 | callbackLogoutStatus({ 385 | result: true 386 | }) 387 | }) 388 | }; 389 | this.updateCookie = function() { 390 | try { 391 | if (me.autoUpdateCookieTime > 5) { 392 | if (updateCookieTimer != null) { 393 | clearTimeout(updateCookieTimer) 394 | } 395 | updateCookieTimer = setTimeout(me.name + ".updateCookie()", me.autoUpdateCookieTime * 1000) 396 | } 397 | var cookieExpireTime = me.getCookieExpireTime(); 398 | var now = (new Date()).getTime() / 1000; 399 | var result = {}; 400 | if (cookieExpireTime == null) { 401 | result = { 402 | retcode: 6102 403 | } 404 | } else { 405 | if (cookieExpireTime < now) { 406 | result = { 407 | retcode: 6203 408 | } 409 | } else { 410 | if (cookieExpireTime - cookieExpireTimeLength + updateCookieTimeHardLimit > now) { 411 | result = { 412 | retcode: 6110 413 | } 414 | } else { 415 | if (cookieExpireTime - now > me.noActiveTime) { 416 | result = { 417 | retcode: 6111 418 | } 419 | } 420 | } 421 | } 422 | } 423 | if (result.retcode !== undefined) { 424 | me.customUpdateCookieCallBack(result); 425 | return false 426 | } 427 | var url = location.protocol == "https:" ? ssoUpdateCookieUrl.replace(/^http:/, "https:") : ssoUpdateCookieUrl; 428 | url = makeURL(url, { 429 | entry: me.getEntry(), 430 | callback: me.name + ".updateCookieCallBack" 431 | }); 432 | excuteScript(me.scriptId, url) 433 | } catch(e) {} 434 | return true 435 | }; 436 | this.setCrossDomainUrlList = function(urlList) { 437 | crossDomainUrlList = urlList 438 | }; 439 | this.checkAltLoginName = function() { 440 | return true 441 | }; 442 | this.callFeedBackUrl = function(loginStatus) { 443 | try { 444 | var request = { 445 | callback: me.name + ".feedBackUrlCallBack" 446 | }; 447 | if (loginStatus.ticket) { 448 | request.ticket = loginStatus.ticket 449 | } 450 | if (loginStatus.retcode !== undefined) { 451 | request.retcode = loginStatus.retcode 452 | } 453 | var url = makeURL(me.feedBackUrl, request); 454 | excuteScript(me.scriptId, url) 455 | } catch(e) {} 456 | return true 457 | }; 458 | this.loginCallBack = function(result) { 459 | try { 460 | if (me.timeoutEnable && !ssoLoginTimer.isset()) { 461 | return 462 | } 463 | ssoLoginTimer.clear(); 464 | me.loginExtraFlag = {}; 465 | var loginStatus = {}; 466 | var st = result.ticket; 467 | var uid = result.uid; 468 | if (uid) { 469 | loginStatus.result = true; 470 | loginStatus.retcode = 0; 471 | loginStatus.userinfo = { 472 | uniqueid: result.uid 473 | }; 474 | if (st) { 475 | loginStatus.ticket = st 476 | } 477 | if (result.cookie) { 478 | loginStatus.cookie = result.cookie 479 | } 480 | if (me.feedBackUrl) { 481 | if (me.crossDomain) { 482 | me.crossDomainAction("login", 483 | function() { 484 | me.callFeedBackUrl(loginStatus) 485 | }) 486 | } else { 487 | me.callFeedBackUrl(loginStatus) 488 | } 489 | } else { 490 | if (me.crossDomain) { 491 | if (result.crossDomainUrlList) { 492 | me.setCrossDomainUrlList({ 493 | retcode: 0, 494 | arrURL: result.crossDomainUrlList 495 | }) 496 | } 497 | me.crossDomainAction("login", 498 | function() { 499 | if (st && me.appLoginURL[me.domain]) { 500 | me.appLogin(st, me.domain, me.name + ".callbackLoginStatus") 501 | } else { 502 | loginStatus.userinfo = objMerge(loginStatus.userinfo, me.getSinaCookie()); 503 | me.callbackLoginStatus(loginStatus) 504 | } 505 | }) 506 | } else { 507 | me.callbackLoginStatus(loginStatus) 508 | } 509 | } 510 | } else { 511 | if (loginMethodCheck && result.retcode == "2092" && me.allowAutoFoundServerTimeError) { 512 | me.setServerTime(0); 513 | me.loginExtraFlag = objMerge(me.loginExtraFlag, { 514 | wsseretry: "servertime_error" 515 | }); 516 | loginMethodCheck(); 517 | loginMethodCheck = null; 518 | return false 519 | } 520 | loginStatus.result = false; 521 | loginStatus.errno = result.retcode; 522 | if (loginStatus.errno == "4069") { 523 | var reason = result.reason.split("|"); 524 | loginStatus.reason = reason[0]; 525 | if (reason.length == 2) { 526 | loginStatus.rurl = reason[1] 527 | } 528 | if (loginStatus.rurl) { 529 | try { 530 | top.location.href = loginStatus.rurl; 531 | return 532 | } catch(e) {} 533 | } 534 | } else { 535 | loginStatus.reason = result.reason 536 | } 537 | me.callbackLoginStatus(loginStatus) 538 | } 539 | } catch(e) {} 540 | return true 541 | }; 542 | this.updateCookieCallBack = function(result) { 543 | if (result.retcode == 0) { 544 | me.crossDomainAction("update", 545 | function() { 546 | me.customUpdateCookieCallBack(result) 547 | }) 548 | } else { 549 | me.customUpdateCookieCallBack(result) 550 | } 551 | }; 552 | this.feedBackUrlCallBack = function(result) { 553 | if (loginMethod == "post" && me.timeoutEnable && !ssoLoginTimer.isset()) { 554 | return 555 | } 556 | if (result.errno == "2092") { 557 | me.setServerTime(0) 558 | } 559 | if (loginMethodCheck && (result.errno == "2092") && me.allowAutoFoundServerTimeError) { 560 | me.loginExtraFlag = objMerge(me.loginExtraFlag, { 561 | wsseretry: "servertime_error" 562 | }); 563 | loginMethodCheck(); 564 | loginMethodCheck = null; 565 | return false 566 | } else { 567 | ssoLoginTimer && ssoLoginTimer.clear() 568 | } 569 | if (result.errno == "4069") { 570 | var reason = result.reason.split("|"); 571 | result.reason = reason[0]; 572 | if (reason.length == 2) { 573 | result.rurl = reason[1]; 574 | try { 575 | top.location.href = result.rurl; 576 | return 577 | } catch(e) {} 578 | } 579 | } 580 | me.callbackLoginStatus(result); 581 | removeNode(me.loginFrameName) 582 | }; 583 | this.doCrossDomainCallBack = function(result) { 584 | me.crossDomainCounter++; 585 | if (result) { 586 | removeNode(result.scriptId) 587 | } 588 | if (me.crossDomainCounter == me.crossDomainCount) { 589 | clearTimeout(crossDomainTimer); 590 | me.crossDomainResult() 591 | } 592 | }; 593 | this.crossDomainCallBack = function(result) { 594 | removeNode(me.ssoCrossDomainScriptId); 595 | if (!result || result.retcode != 0) { 596 | return false 597 | } 598 | var arrURL = result.arrURL; 599 | var url, scriptId; 600 | var request = { 601 | callback: me.name + ".doCrossDomainCallBack" 602 | }; 603 | me.crossDomainCount = arrURL.length; 604 | me.crossDomainCounter = 0; 605 | if (arrURL.length == 0) { 606 | clearTimeout(crossDomainTimer); 607 | me.crossDomainResult(); 608 | return true 609 | } 610 | for (var i = 0; i < arrURL.length; i++) { 611 | url = arrURL[i]; 612 | scriptId = "ssoscript" + i; 613 | request.scriptId = scriptId; 614 | url = makeURL(url, request); 615 | if (isSafari()) { 616 | excuteIframe(scriptId, url) 617 | } else { 618 | excuteScript(scriptId, url) 619 | } 620 | } 621 | }; 622 | this.crossDomainResult = function() { 623 | crossDomainUrlList = null; 624 | if (typeof crossDomainForward == "function") { 625 | crossDomainForward() 626 | } 627 | }; 628 | this.crossDomainAction = function(action, callback) { 629 | crossDomainTimer = setTimeout(me.name + ".crossDomainResult()", crossDomainTime * 1000); 630 | if (typeof callback == "function") { 631 | crossDomainForward = callback 632 | } else { 633 | crossDomainForward = null 634 | } 635 | if (crossDomainUrlList) { 636 | me.crossDomainCallBack(crossDomainUrlList); 637 | return false 638 | } 639 | var domain = me.domain; 640 | if (action == "update") { 641 | action = "login"; 642 | domain = "sina.com.cn" 643 | } 644 | var request = { 645 | scriptId: me.ssoCrossDomainScriptId, 646 | callback: me.name + ".crossDomainCallBack", 647 | action: action, 648 | domain: domain, 649 | sr: window.screen.width + "*" + window.screen.height 650 | }; 651 | var url = makeURL(ssoCrosssDomainUrl, request); 652 | excuteScript(me.ssoCrossDomainScriptId, url) 653 | }; 654 | this.checkLoginState = function(callback) { 655 | if (callback) { 656 | me.autoLogin(callback) 657 | } else { 658 | me.autoLogin(function(cookieinfo) { 659 | var loginStatus = {}; 660 | if (cookieinfo !== null) { 661 | var userinfo = { 662 | displayname: cookieinfo.nick, 663 | uniqueid: cookieinfo.uid, 664 | userid: cookieinfo.user 665 | }; 666 | loginStatus.result = true; 667 | loginStatus.userinfo = userinfo 668 | } else { 669 | loginStatus.result = false; 670 | loginStatus.reason = "" 671 | } 672 | me.callbackLoginStatus(loginStatus) 673 | }) 674 | } 675 | }; 676 | this.getCookieExpireTime = function() { 677 | return getCookieExpireTimeByDomain(me.domain) 678 | }; 679 | this.getSinaCookie = function(strict) { 680 | var sup = urldecode(getCookie("SUP")); 681 | if (!sup && !urldecode(getCookie("ALF"))) { 682 | return null 683 | } 684 | if (!sup) { 685 | sup = urldecode(getCookie("SUR")) 686 | } 687 | if (!sup) { 688 | return null 689 | } 690 | var arrSup = parse_str(sup); 691 | if (strict && arrSup.et && (arrSup.et * 1000 < (new Date()).getTime())) { 692 | return null 693 | } 694 | return arrSup 695 | }; 696 | this.get51UCCookie = function() { 697 | return me.getSinaCookie() 698 | }; 699 | this.isPreLoginState = function() { 700 | var subp = getCookie("SUBP"); 701 | if (!subp) { 702 | return false 703 | } 704 | var subp_obj = sinaSSOEncoder.getSUBPCookie.decode(subp); 705 | if (subp_obj && subp_obj.status == "40") { 706 | return true 707 | } 708 | return false 709 | }; 710 | this.isVisitor = function() { 711 | var subp = getCookie("SUBP"); 712 | if (!subp) { 713 | return false 714 | } 715 | var subp_obj = sinaSSOEncoder.getSUBPCookie.decode(subp); 716 | if (subp_obj && subp_obj.status == "20") { 717 | return true 718 | } 719 | return false 720 | }; 721 | this.autoLogin = function(callback, strict) { 722 | if (me.domain == "sina.com.cn") { 723 | if (getCookie("SUP") === null && getCookie("ALF") !== null) { 724 | sinaAutoLogin(callback); 725 | return true 726 | } 727 | } else { 728 | if (getCookie("SUP") === null && (strict || getCookie("SSOLoginState") !== null || getCookie("ALF") !== null)) { 729 | sinaAutoLogin(callback); 730 | return true 731 | } 732 | } 733 | callback(me.getSinaCookie()); 734 | return true 735 | }; 736 | this.autoLoginCallBack2 = function(result) { 737 | try { 738 | autoLoginCallBack2(me.getSinaCookie()) 739 | } catch(e) {} 740 | return true 741 | }; 742 | this.appLogin = function(ticket, domain, callback) { 743 | var savestate = tmpData.savestate ? parseInt((new Date()).getTime() / 1000 + tmpData.savestate * 86400) : 0; 744 | var alf = getCookie("ALF") ? getCookie("ALF") : 0; 745 | var request = { 746 | callback: callback, 747 | ticket: ticket, 748 | ssosavestate: savestate || alf 749 | }; 750 | var appLoginURL = me.appLoginURL[domain]; 751 | var url = makeURL(appLoginURL, request); 752 | excuteScript(me.scriptId, url, "gb2312"); 753 | return true 754 | }; 755 | this.autoLoginCallBack3 = function(result) { 756 | if (result.retcode != 0) { 757 | me.autoLoginCallBack2(result); 758 | return false 759 | } 760 | var domain = me.domain == "sina.com.cn" ? "weibo.com": me.domain; 761 | me.appLogin(result.ticket, domain, me.name + ".autoLoginCallBack2"); 762 | return true 763 | }; 764 | this.setLoginType = function(loginType) { 765 | var https = location.protocol == "https:" ? me.https: 0; 766 | if (https) { 767 | me.crossDomain = false 768 | } 769 | me.loginType = loginType | https; 770 | return true 771 | }; 772 | this.setServerTime = function(servertime) { 773 | if (!ssoServerTimeTimer) { 774 | ssoServerTimeTimer = new prototypeTimer(true) 775 | } 776 | if (servertime == 0) { 777 | ssoServerTimeTimer.clear(); 778 | me.servertime = servertime; 779 | return true 780 | } 781 | if (servertime < 1294935546) { 782 | return false 783 | } 784 | var calcServerTime = function() { 785 | if (me.servertime) { 786 | me.servertime += me.calcServerTimeInterval / 1000; 787 | ssoServerTimeTimer.start(me.calcServerTimeInterval, calcServerTime) 788 | } 789 | }; 790 | me.servertime = servertime; 791 | ssoServerTimeTimer.start(me.calcServerTimeInterval, calcServerTime) 792 | }; 793 | this.getPinCodeUrl = function(size) { 794 | if (size == undefined) { 795 | size = 0 796 | } 797 | if (pcid) { 798 | me.loginExtraQuery.pcid = pcid 799 | } 800 | var url = location.protocol == "https:" ? pincodeUrl.replace(/^http:/, "https:") : pincodeUrl; 801 | return url + "?r=" + Math.floor(Math.random() * 100000000) + "&s=" + size + (pcid.length > 0 ? "&p=" + pcid: "") 802 | }; 803 | this.showPinCode = function(id) { 804 | me.$(id).src = me.getPinCodeUrl() 805 | }; 806 | this.isVfValid = function() { 807 | return me.getSinaCookie(true)["vf"] != 1 808 | }; 809 | this.getVfValidUrl = function() { 810 | return vfValidUrl 811 | }; 812 | this.enableFailRedirect = function() { 813 | me.failRedirect = true 814 | }; 815 | var makeNonce = function(len) { 816 | var x = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 817 | var str = ""; 818 | for (var i = 0; i < len; i++) { 819 | str += x.charAt(Math.ceil(Math.random() * 1000000) % x.length) 820 | } 821 | return str 822 | }; 823 | var sinaAutoLogin = function(callback) { 824 | autoLoginCallBack2 = callback; 825 | var request = { 826 | entry: me.getEntry(), 827 | service: me.service, 828 | encoding: "UTF-8", 829 | gateway: 1, 830 | returntype: "TEXT", 831 | from: me.from 832 | }; 833 | if (me.domain == "sina.com.cn") { 834 | request.callback = me.name + ".autoLoginCallBack3"; 835 | request.service = "miniblog"; 836 | request.useticket = 1 837 | } else { 838 | request.callback = me.name + ".autoLoginCallBack3"; 839 | request.useticket = 1 840 | } 841 | var url = location.protocol == "https:" ? ssoLoginUrl.replace(/^http:/, "https:") : ssoLoginUrl; 842 | url = makeURL(url, request); 843 | excuteScript(me.scriptId, url, "gb2312"); 844 | return true 845 | }; 846 | var getCookieExpireTimeByDomain = function(domain) { 847 | var expireTime = null; 848 | var cookie = null; 849 | cookie = me.getSinaCookie(); 850 | if (cookie) { 851 | expireTime = cookie.et 852 | } 853 | return expireTime 854 | }; 855 | var addEventListener = function(dom, eventName, fn) { 856 | if (dom.addEventListener) { 857 | dom.addEventListener(eventName, fn, false) 858 | } else { 859 | if (dom.attachEvent) { 860 | dom.attachEvent("on" + eventName, fn) 861 | } else { 862 | dom["on" + eventName] = fn 863 | } 864 | } 865 | }; 866 | var prototypeTimer = function(enable) { 867 | var mytimer = false; 868 | this.start = function(timeout, callback) { 869 | if (enable) { 870 | mytimer = setTimeout(callback, timeout) 871 | } 872 | }; 873 | this.clear = function(name) { 874 | if (enable) { 875 | clearTimeout(mytimer); 876 | mytimer = false 877 | } 878 | }; 879 | this.isset = function() { 880 | return mytimer !== false 881 | } 882 | }; 883 | var excuteScript = function(id, scriptSource, charset) { 884 | removeNode(id); 885 | var head = document.getElementsByTagName("head")[0]; 886 | var newScript = document.createElement("script"); 887 | newScript.charset = charset || "gb2312"; 888 | newScript.id = id; 889 | newScript.type = "text/javascript"; 890 | newScript.src = makeURL(scriptSource, { 891 | client: me.getClientType(), 892 | _: (new Date()).getTime() 893 | }); 894 | head.appendChild(newScript) 895 | }; 896 | var excuteIframe = function(id, url) { 897 | removeNode(id); 898 | var bodyel = document.getElementsByTagName("body")[0]; 899 | var new_iframe = document.createElement("iframe"); 900 | new_iframe.style.display = "none"; 901 | new_iframe.src = makeURL(url, { 902 | client: me.getClientType(), 903 | _: (new Date()).getTime() 904 | }); 905 | new_iframe.isReady = false; 906 | addEventListener(new_iframe, "load", 907 | function() { 908 | if (new_iframe.isReady) { 909 | return 910 | } 911 | new_iframe.isReady = true; 912 | me.doCrossDomainCallBack({ 913 | scriptId: id 914 | }) 915 | }); 916 | bodyel.appendChild(new_iframe) 917 | }; 918 | var makeRequest = function(username, password, savestate) { 919 | var request = { 920 | entry: me.getEntry(), 921 | gateway: 1, 922 | from: me.from, 923 | savestate: savestate, 924 | useticket: me.useTicket ? 1 : 0 925 | }; 926 | if (me.failRedirect) { 927 | me.loginExtraQuery.frd = 1 928 | } 929 | request = objMerge(request, { 930 | pagerefer: document.referrer || "" 931 | }); 932 | request = objMerge(request, me.loginExtraFlag); 933 | request = objMerge(request, me.loginExtraQuery); 934 | request.su = sinaSSOEncoder.base64.encode(urlencode(username)); 935 | if (me.service) { 936 | request.service = me.service 937 | } 938 | if ((me.loginType & rsa) && me.servertime && sinaSSOEncoder && sinaSSOEncoder.RSAKey) { 939 | request.servertime = me.servertime; 940 | request.nonce = me.nonce; 941 | request.pwencode = "rsa2"; 942 | request.rsakv = me.rsakv; 943 | var RSAKey = new sinaSSOEncoder.RSAKey(); 944 | RSAKey.setPublic(me.rsaPubkey, "10001"); 945 | password = RSAKey.encrypt([me.servertime, me.nonce].join("\t") + "\n" + password) 946 | } else { 947 | if ((me.loginType & wsse) && me.servertime && sinaSSOEncoder && sinaSSOEncoder.hex_sha1) { 948 | request.servertime = me.servertime; 949 | request.nonce = me.nonce; 950 | request.pwencode = "wsse"; 951 | password = sinaSSOEncoder.hex_sha1("" + sinaSSOEncoder.hex_sha1(sinaSSOEncoder.hex_sha1(password)) + me.servertime + me.nonce) 952 | } 953 | } 954 | request.sp = password; 955 | try { 956 | request.sr = window.screen.width + "*" + window.screen.height 957 | } catch(e) {} 958 | return request 959 | }; 960 | var loginByXMLHttpRequest = function(username, password, savestate) { 961 | if (typeof XMLHttpRequest == "undefined") { 962 | return false 963 | } 964 | var xhr = new XMLHttpRequest(); 965 | if (!"withCredentials" in xhr) { 966 | return false 967 | } 968 | var request = makeXMLRequestQuery(username, password, savestate); 969 | var url = (me.loginType & https) ? ssoLoginUrl.replace(/^http:/, "https:") : ssoLoginUrl; 970 | url = makeURL(url, { 971 | client: me.getClientType(), 972 | _: (new Date()).getTime() 973 | }); 974 | try { 975 | xhr.open("POST", url, true); 976 | xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 977 | xhr.withCredentials = true; 978 | xhr.onreadystatechange = function() { 979 | if (xhr.readyState == 4 && xhr.status == 200) { 980 | me.loginCallBack(parseJSON(xhr.responseText)) 981 | } 982 | }; 983 | xhr.send(httpBuildQuery(request)) 984 | } catch(e) { 985 | return false 986 | } 987 | return true 988 | }; 989 | var makeXMLRequestQuery = function(username, password, savestate) { 990 | if (me.appLoginURL[me.domain]) { 991 | me.useTicket = 1; 992 | me.service = me.appDomainService[me.domain] || me.service 993 | } 994 | var cdult = 0; 995 | if (me.domain) { 996 | cdult = 2 997 | } 998 | if (!me.appLoginURL[me.domain]) { 999 | cdult = 3 1000 | } 1001 | if (me.cdult !== false) { 1002 | cdult = me.cdult 1003 | } 1004 | if (cdult == 3) { 1005 | crossDomainTime = me.crossDomainTime; 1006 | delete me.appLoginURL[me.domain] 1007 | } 1008 | var request = makeRequest(username, password, savestate); 1009 | return objMerge(request, { 1010 | encoding: "UTF-8", 1011 | cdult: cdult, 1012 | domain: me.domain, 1013 | useticket: me.appLoginURL[me.domain] ? 1 : 0, 1014 | prelt: preloginTime, 1015 | returntype: "TEXT" 1016 | }) 1017 | }; 1018 | var loginByScript = function(username, password, savestate) { 1019 | var request = makeXMLRequestQuery(username, password, savestate); 1020 | request = objMerge(request, { 1021 | callback: me.name + ".loginCallBack" 1022 | }); 1023 | var url = (me.loginType & https) ? ssoLoginUrl.replace(/^http:/, "https:") : ssoLoginUrl; 1024 | url = makeURL(url, request); 1025 | excuteScript(me.scriptId, url, "gb2312") 1026 | }; 1027 | var loginByIframe = function(username, password, savestate) { 1028 | createIFrame(me.loginFrameName); 1029 | var loginForm = createForm(me.loginFormId); 1030 | var request = makeRequest(username, password, savestate); 1031 | request.encoding = "UTF-8"; 1032 | if (me.crossDomain == false) { 1033 | request.crossdomain = 0 1034 | } 1035 | request.prelt = preloginTime; 1036 | if (me.feedBackUrl) { 1037 | request.url = makeURL(me.feedBackUrl, { 1038 | framelogin: 1, 1039 | callback: "parent." + me.name + ".feedBackUrlCallBack" 1040 | }); 1041 | request.returntype = "META" 1042 | } else { 1043 | request.callback = "parent." + me.name + ".loginCallBack"; 1044 | request.returntype = "IFRAME"; 1045 | request.setdomain = me.setDomain ? 1 : 0 1046 | } 1047 | for (var key in me.loginExtraQuery) { 1048 | if (typeof me.loginExtraQuery[key] == "function") { 1049 | continue 1050 | } 1051 | request[key] = me.loginExtraQuery[key] 1052 | } 1053 | for (var name in request) { 1054 | loginForm.addInput(name, request[name]) 1055 | } 1056 | var action = (me.loginType & https) ? ssoLoginUrl.replace(/^http:/, "https:") : ssoLoginUrl; 1057 | action = makeURL(action, objMerge({ 1058 | client: me.getClientType() 1059 | }, 1060 | me.loginExtraFlag)); 1061 | loginForm.method = "post"; 1062 | loginForm.action = action; 1063 | loginForm.target = me.loginFrameName; 1064 | var result = true; 1065 | try { 1066 | loginForm.submit() 1067 | } catch(e) { 1068 | removeNode(me.loginFrameName); 1069 | result = false 1070 | } 1071 | setTimeout(function() { 1072 | removeNode(loginForm) 1073 | }, 1074 | 10); 1075 | return result 1076 | }; 1077 | var createIFrame = function(frameName, src) { 1078 | if (src == null) { 1079 | src = "javascript:false;" 1080 | } 1081 | removeNode(frameName); 1082 | var frame = document.createElement("iframe"); 1083 | frame.height = 0; 1084 | frame.width = 0; 1085 | frame.style.display = "none"; 1086 | frame.name = frameName; 1087 | frame.id = frameName; 1088 | frame.src = src; 1089 | appendChild(document.body, frame); 1090 | window.frames[frameName].name = frameName; 1091 | return frame 1092 | }; 1093 | var createForm = function(formName, display) { 1094 | if (display == null) { 1095 | display = "none" 1096 | } 1097 | removeNode(formName); 1098 | var form = document.createElement("form"); 1099 | form.height = 0; 1100 | form.width = 0; 1101 | form.style.display = display; 1102 | form.name = formName; 1103 | form.id = formName; 1104 | appendChild(document.body, form); 1105 | document.forms[formName].name = formName; 1106 | form.addInput = function(name, value, type) { 1107 | if (type == null) { 1108 | type = "text" 1109 | } 1110 | var _name = this.getElementsByTagName("input")[name]; 1111 | if (_name) { 1112 | this.removeChild(_name) 1113 | } 1114 | _name = document.createElement("input"); 1115 | this.appendChild(_name); 1116 | _name.id = name; 1117 | _name.name = name; 1118 | _name.type = type; 1119 | _name.value = value 1120 | }; 1121 | return form 1122 | }; 1123 | var removeNode = function(el) { 1124 | try { 1125 | if (typeof(el) === "string") { 1126 | el = me.$(el) 1127 | } 1128 | el.parentNode.removeChild(el) 1129 | } catch(e) {} 1130 | }; 1131 | var getType = function(item) { 1132 | if (typeof(item) === "undefined") { 1133 | return "undefined" 1134 | } 1135 | if (item === null) { 1136 | return "null" 1137 | } 1138 | return Object.prototype.toString.call(item).replace(/^\[object\s|\]$/gi, "").toLowerCase() 1139 | }; 1140 | var isSafari = function() { 1141 | var browserName = navigator.userAgent.toLowerCase(); 1142 | return ((/webkit/i).test(browserName) && !(/chrome/i).test(browserName)) 1143 | }; 1144 | var appendChild = function(parentObj, element) { 1145 | parentObj.appendChild(element) 1146 | }; 1147 | var getCookie = function(name) { 1148 | var Res = (new RegExp(name + "=([^;]+)")).exec(document.cookie); 1149 | return Res == null ? null: Res[1] 1150 | }; 1151 | var makeURL = function(url, request) { 1152 | return url + urlAndChar(url) + httpBuildQuery(request) 1153 | }; 1154 | var urlAndChar = function(url) { 1155 | return (/\?/.test(url) ? "&": "?") 1156 | }; 1157 | var urlencode = function(str) { 1158 | return encodeURIComponent(str) 1159 | }; 1160 | var urldecode = function(str) { 1161 | if (str == null) { 1162 | return "" 1163 | } else { 1164 | try { 1165 | return decodeURIComponent(str) 1166 | } catch(e) { 1167 | return "" 1168 | } 1169 | } 1170 | }; 1171 | var httpBuildQuery = function(obj) { 1172 | if (typeof obj != "object") { 1173 | return "" 1174 | } 1175 | var arr = new Array(); 1176 | for (var key in obj) { 1177 | if (typeof obj[key] == "function") { 1178 | continue 1179 | } 1180 | arr.push(key + "=" + urlencode(obj[key])) 1181 | } 1182 | return arr.join("&") 1183 | }; 1184 | var parse_str = function(str) { 1185 | var arr = str.split("&"); 1186 | var arrtmp; 1187 | var arrResult = {}; 1188 | for (var i = 0; i < arr.length; i++) { 1189 | arrtmp = arr[i].split("="); 1190 | arrResult[arrtmp[0]] = urldecode(arrtmp[1]) 1191 | } 1192 | return arrResult 1193 | }; 1194 | var parseJSON = function(str) { 1195 | if (typeof(str) === "object") { 1196 | return str 1197 | } else { 1198 | if (window.JSON) { 1199 | return JSON.parse(str) 1200 | } else { 1201 | return eval("(" + str + ")") 1202 | } 1203 | } 1204 | }; 1205 | var objMerge = function(obj1, obj2) { 1206 | for (var item in obj2) { 1207 | obj1[item] = obj2[item] 1208 | } 1209 | return obj1 1210 | }; 1211 | this.$ = function(id) { 1212 | return document.getElementById(id) 1213 | }; 1214 | this.generateVisitor = function() { 1215 | var reg, domainValid = false; 1216 | for (var i = 0; i < this.generateVisitorDomain.length; i++) { 1217 | reg = new RegExp(this.generateVisitorDomain[i]); 1218 | if (reg.test(document.domain)) { 1219 | domainValid = true; 1220 | break 1221 | } 1222 | } 1223 | if (!domainValid) { 1224 | return false 1225 | } 1226 | try { 1227 | if (me.shouldGenerateVisitor() && !me.$("visitorfrm84747h4784")) { 1228 | document.body.insertAdjacentHTML("beforeEnd", "