前言
大部分公司都會(huì)給碼農(nóng)們安排一項(xiàng)每天必做的任務(wù),那就是日?qǐng)?bào)。有發(fā)郵件的、用trello的、用worktile(國內(nèi)山寨版trello)等其他項(xiàng)目工具的。
隨著微信紅包的普及筆者所在的項(xiàng)目組不及時(shí)寫日?qǐng)?bào)也要發(fā)紅包了。規(guī)則很簡單每天23點(diǎn)之前沒有在trello上填寫當(dāng)日的日?qǐng)?bào)就要在項(xiàng)目組微信群內(nèi)發(fā)20塊錢的紅包。
山
是山的影子
狗
懶得進(jìn)化
夏天
人的酶很固執(zhí)
靈魂的酶像荷花
——《路邊野餐》
一日午覺后,一個(gè)想法出現(xiàn)在了心中,可以做一個(gè)工具定時(shí)每天22:30的時(shí)候掃一遍trello看看哪些小伙們的日?qǐng)?bào)還沒有寫,然后發(fā)短信通知他們。那么首當(dāng)其沖就是要搞清楚trello的登錄校驗(yàn)邏輯,遂有了此文。
進(jìn)入正題~
打開Trello登錄頁面 https://trello.com/login
開啟Chrome開發(fā)者工具
勾上Preserve log(不勾上,當(dāng)頁面跳轉(zhuǎn)后之前頁面的網(wǎng)絡(luò)請(qǐng)求日志會(huì)被清掉)
如下圖

成功登錄后到Welcome Board
以Welcome Board為例

抓到請(qǐng)求獲取數(shù)據(jù)的接口地址
接下來用Paw來嘗試請(qǐng)求

意料之中返回401,header中沒加授權(quán)信息是肯定不行滴
授權(quán)信息一般都是存在cookies里面,那么到chrome中找到請(qǐng)求這個(gè)接口的cookie

cookie:
__qca=P0-1593696850-1468204008719;
mab=56c3d4635bb906467b8d3b7c;
hsfirstvisit=https%3A%2F%2Ftrello.com%2Flogged-out|https%3A%2F%2Ftrello.com%2F|1470972765622;
lang=zh-CN;
dsc=ec5a4132373a500487514ee1e6fd6ef40b5456283e512841026d16a8639951cb;
__leadinmigrated=1;
__leadinutk=ee14b39f2824ae1221e4582c81e468d9;
__hstc=183819321.ee14b39f2824ae1221e4582c81e468d9.1470972765624.1471414624578.1471424173893.4;
__hssrc=1;
hubspotutk=ee14b39f2824ae1221e4582c81e468d9;
token=56c3d4635bb906467b8d3b7c%2FunNor91IDg3STWzPAq7ETuozz6kOPIBOHx6HOdN1m62CvUshibAq3ZCAFClwdrHQ;
hasAccount=password;
_sp_id.dc4d=e2c0b466013c63ff.1468204012.39.1471426756.1471414838.715caf7e-ee7c-4f66-aa95-d4262ce0eba0;
_sp_ses.dc4d=*;
_ga=GA1.2.1122412242.1468204008
將cookie信息加到header中再用Paw嘗試

成功請(qǐng)求到數(shù)據(jù)啦~
多次嘗試發(fā)現(xiàn)cookies里面真正有用的參數(shù)只有token
token=56c3d4635bb906467b8d3b7c%2FunNor91IDg3STWzPAq7ETuozz6kOPIBOHx6HOdN1m62CvUshibAq3ZCAFClwdrHQ;
那么接下來目標(biāo)就清晰了,只要從登錄接口獲取到token之后就可以任意調(diào)接口拿數(shù)據(jù)了
獲取Token
再回到登錄頁面,點(diǎn)擊登錄

看請(qǐng)求的接口,主要是兩個(gè)authentication和session
分析這兩個(gè)接口可以發(fā)現(xiàn)獲取token的流程:
- 用賬號(hào)、密碼請(qǐng)求接口獲取code

- 用code和一個(gè)隨機(jī)數(shù)獲取token


這里要注意cookie中的dsc和請(qǐng)求參數(shù)中的dsc要一致
最后從response headers中取出token就大功告成啦!??
代碼實(shí)現(xiàn)(NodeJS)
var superagent = require('superagent');
var uuid = require('node-uuid');
function authentication(username, password, cb) {
superagent.post('https://trello.com/1/authentication')
.send('method=' + 'password')
.send('factors[user]=' + username)
.send('factors[password]=' + password)
.end(function (err, res) {
console.log("response status:" + res.status);
if (!err) {
var code = JSON.parse(res.text).code;
cb(code);
}
});
}
function session(code, dsc, cb) {
superagent.post('https://trello.com/1/authorization/session')
.set('Cookie', 'dsc=' + dsc)
.send('authentication=' + code)
.send('dsc=' + dsc)
.end(function (err, res) {
if (!err) {
var cookie = res.headers['set-cookie'][0];
cb(cookie);
}
})
}
function requestData(cookie, cb){
superagent.get('https://trello.com/1/Boards/EAncSndA?lists=open&cards=visible&card_stickers=true&card_fields=desc,idList,name&card_checklists=none&members=all&member_fields=fullName,initials,memberType,username,avatarHash,bio,bioData,confirmed,products,url,status&membersInvited=all&membersInvited_fields=fullName,initials,memberType,username,avatarHash,bio,bioData,confirmed,products,url&memberships_orgMemberType=true&checklists=none&organization=true&organization_fields=name,displayName,desc,url,website,logoHash&myPrefs=true&fields=name,closed,dateLastActivity,dateLastView,idOrganization,prefs,shortLink,shortUrl,url,desc,descData,invitations,invited,labelNames,memberships,pinned,powerUps,subscribed')
.set('Cookie', cookie)
.end(function (err, res) {
if(!err){
cb(res.text)
}
})
}
module.exports = {
requestData: function (username, password, cb) {
var dsc = uuid.v4();
authentication(username, password, function (code) {
session(code, dsc, function (cookie) {
requestData(cookie, function (data) {
cb(data);
});
})
})
}
}