测试的同学突然跟我说要在Nodejs上调起Jenkins(https://jenkins.io/)构建,我首先想到就是调用Jenkins的API,但是具体怎么做呢?
通过fiddler(http://www.telerik.com/fiddler)找到点击构建时候调用的API:
找到了类似 POST: http://jenkins_url/view//job/... 结构API
I get you! 讲道理通过直接post到上述接口就可以了,当然要复制cookie以绕开登录。说干就干,在ARC(Advanced REST client)添加URL,拷贝cookie进去,点击发送,发现以下错误:
Error 403 No valid crumb was included in the request
这个明显就是CSRF校验挡住了我的路。虽然我总喜欢在自己的项目加CSRF校验,但是无比讨厌别人的站点也加,这个明显就是不让我做坏事嘛。但是简单的CSRF就能阻止程序员搞事情么?开玩笑!
根据CSRF的原理,要破也是很简单的嘛。首先我们可以向服务器请求一次拿到一个token值,然后再发第二次请求时带上token就可以了。
先去Google搜一下"jenkins CSRF",找到这样一篇文章,https://wiki.jenkins.io/displ...
jenkins官方wiki就提供了完整方法。
CSRF Protection
If your Jenkins uses the "Prevent Cross Site Request Forgery exploits" security option (which it should), when you make a POST request, you have to send a CSRF protection token as an HTTP request header.
For curl/wget you can obtain the header needed in the request from the URL JENKINS_URL/crumbIssuer/api/xml (or .../api/json). Something like this:
wget -q --auth-no-challenge --user USERNAME --password PASSWORD --output-document - \
'JENKINS_URL/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'
还好我略懂英文。文章已经很清楚地指出可以通过GET JENKINS_URL/crumbIssuer/api/xml的方式拿到一个crumbRequestField和crumb,然后在下一次请求带上就可以了。
上面的代码转换成常规http请求就是:
get: http://USERNAME:PASSWORD@JENKINS_URL/crumbIssuer/api/xml
我查了一下文档,发现其实也可以用json
get: http://USERNAME:PASSWORD@JENKINS_URL/crumbIssuer/api/json
注意: 一定不能忘了加USERNAME:PASSWORD哦
那些喜欢用curl的同学可以用以下的语句:
curl -X GET http:/JENKINS_URL/crumbIssuer/api/json --user USERNAME:PASSWORD
返回的结果结构如下:
{"_class":"hudson.security.csrf.DefaultCrumbIssuer","crumb":"******","crumbRequestField":"Jenkins-Crumb"}
拿到crumb之后放到请求头就可以了,例如我用curl可以这样写:
curl -X POST JENKINS_URL/job/JOB_NAME/build \
--user USER:PASSWORD \
--header "Jenkins-Crumb:***"
执行一下,发现jenkins可以自动构建了,打完收工。
有安全洁癖的同学看到USERNAME:PASSWORD就很不爽,其实可以用token代替password, 即USERNAME:TOKEN
在用户设置中可以看到自己的Token
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。