Published at: 08:10 pm - Thursday October 15 2009
今天又讨论了一种验证码服务的机制,这种机制相对前两天说的简化的验证码生成的部分,由两步生成变成了一步生成,当然由于生成图片的接口直接暴露给用户,存在被刷的可能。 用户浏览器向应用服务器请求包含验证码的页面; 应用服务器将包含验证码地址的网页发送给用户浏览器; 用户浏览器通过img的src中的固定链接向验证码服务器请求验证码图片; 验证码服务器输出验证码图片流到用户浏览器,将sessionid写入cookie; 用户判读验证码图片,提交表单; 应用服务器取出cookie中的sessionid和用户输入发往验证码服务器; 验证码服务器进行验证,返回通过或拒绝; 应用服务器根据验证码服务器结果进行响应。 优点: 固定链接,简化了接入,便于接入静态页面; 缺点: 写cookie受到域的限制,只能在相同的域中使用该服务; 验证码接口暴露给用户,可能被穷举 百度和腾讯使用的都是这种方式。
Published at: 05:10 pm - Tuesday October 13 2009
某人已经发展到上班时间写blog了。 继续说验证码服务,找到两个比较典型的。recaptcha非常著名,是twitter和facebook使用的验证码服务(不知道现在的情况。。。),vidoop提供了一种很有特点的验证码机制。 两个服务都提供了python的接口封装便于接入,通过api接口可以管中窥豹,大致了解这两个验证服务的机制。 recaptcha 下面是一段结合了web.py的简单调用 public_key = “******” private_key = “********” class Recaptcha(object): def GET(self): r = recaptcha.displayhtml(public_key) return render.recapt(r) def POST(self): params = web.input() recaptcha_challenge_field, recaptcha_response_field = params.recaptcha_challenge_field, params.recaptcha_response_field remote_ip = web.ctx.ip result = recaptcha.submit(recaptcha_challenge_field, recaptcha_response_field, private_key, remote_ip) return result.is_valid 我在GET请求中获取验证码,在POST请求中提交验证码。 recaptcha返回的是一段recaptcha自己风格的html片段,效果大家参考twitter的验证码,实际上是一个iframe,iframe的url中包含了哈希串。其中的字段名也自然被写死成recaptcha_challenge_field和recaptcha_response_field,考虑到应用服务器无需验证这两个field的输入,所以也无可厚非。recaptcha_response_field用于输入字符,recaptcha_challenge_field在载入时被修改为一个唯一key。 提交验证时,recaptcha需要提供以上两个用户输入和应用的privatekey以及浏览器ip。recaptcha通过recaptcha_challenge_field 应用的private key以及用户出口ip可以唯一标示用户,并包含一些冗余实现安全相关策略。 Vidoop Vidoop提供的服务机制与recaptcha大同小异 customer_id = “***” site_id = “localtest” api_username [...]
Published at: 09:10 pm - Monday October 12 2009
方式1,应用服务器负责生成验证码字符,验证码服务器主要负责验证码图片生成。 用户浏览器向应用服务器请求包含验证码的页面; 应用服务器生成验证码字符,存储在session中;应用服务器发送相关图片参数(验证码字符、宽、高、复杂度、背景色等)到验证码服务器; 验证码服务器返回图片地址到应用服务器; 应用服务器将包含验证码地址的网页发送给用户浏览器; 用户浏览器通过img的src方式向验证码服务器请求验证码图片; 验证码服务器输出验证码图片流到用户浏览器; 用户判读验证码图片,提交表单; 应用服务器取出session中的验证码字符比对,返回结果。 这种方式的优点: 较少的HTTP请求调用 替换原应用中独立的验证码功能相对容易 验证码服务器相对简单 方式2,验证码服务器承担验证功能,应用服务器在验证中仅起到传递作用。 用户浏览器向应用服务器请求包含验证码的页面; 应用服务器发送相关图片参数(宽、高、复杂度、背景色等)到验证码服务器; 验证码服务器返回图片地址、惟一的会话id到应用服务器; 应用服务器将包含验证码地址的网页发送给用户浏览器; 用户浏览器通过img的src方式向验证码服务器请求验证码图片; 验证码服务器输出验证码图片流到用户浏览器; 用户判读验证码图片,提交表单; 应用服务器将第三步获得的会话id和用户输入的验证码字符传给验证码服务器; 验证码服务器进行验证,返回通过或拒绝; 应用服务器根据验证码服务器结果进行响应。 这种方式的优点: 验证码服务功能完善,涵盖整个验证流程; 验证码服务端有详细的验证日志记录,便于数据分析; 欢迎大家就两种方式发表意见~
Published at: 10:09 pm - Tuesday September 29 2009
半年没碰那个首页了,最近看到commandlinefu提供了jsonp接口,顺手把commandlinefu加了进来: Classicning7.clifu(); 这个程序是去年此时还在用JavaScript工作的时候写的,隔了一年再看,很难不感慨啊。话说,大家要是发现一些好玩的,好用的JSONP服务可以分享一下。
Published at: 08:08 pm - Monday August 24 2009
YAMB(Yet Another Microblogging Tool) which is mentioned several days ago is now hosted on Sun’s project-kenai licensed with GPL2. http://kenai.com/projects/yamb You can grab the source code from following link via mercurial(hg). https://kenai.com/hg/yamb~hg-repos Actually, there is nothing new.
Published at: 10:08 pm - Friday August 07 2009
Grails的在Servlet API的基础上增加了一个非常实用的FlashScope,FlashScope的生命周期为两次请求(也就是在一次重定向)。它的典型应用是POST方式提交后显示服务器端发给用户的提示信息,在平时的应用中会经常使用。 Grails的FlashScope接口定义在org.codehaus.groovy.grails.web.servlet包中,这个接口继承了Map接口,并定义了一个方法next()。 Grails的默认实现在org.codehaus.groovy.grails.web.servlet包中,GrailsFlashScope。这个实现内部定义了两个Map(生命周期为两个请求),current和next,这两个Map不断滚动,保持在一个请求中可以且仅可以访问到当前和前一次请求的上下文。 [codesyntax lang="java"] public void next() { current.clear(); current = (HashMap)next.clone(); next.clear(); reassociateObjectsWithErrors(current); } [/codesyntax] put的时候,Grails只把新制放到next表中,因为next将在下一次请求时继续保存 [codesyntax lang="java"] public Object put(Object key, Object value) { // create the session if it doesn’t exist registerWithSessionIfNecessary(); if(current.containsKey(key)) { current.remove(key); } storeErrorsIfPossible(next,value); return next.put(key,value); } [/codesyntax] get的时候,Grails在两个Map中查找 [codesyntax lang="java"] public Object get(Object key) { if(next.containsKey(key)) [...]
Published at: 10:08 pm - Monday August 03 2009
A simple micro blogging tool based on Java web framework stack (Struts2/Spring/iBatis). It costs me five days to develop such a prototype version which supports basic functions(view, post, follow and tag). And I will try to deploy it on GAE later(I hope it is possible). More improvements will also come up in next severals day. [...]
Published at: 03:08 pm - Sunday August 02 2009
异步、模拟多线程式的JavaScript,防止界面锁死。例如Google Gears,Firefox3.5 WebWorker异步API。 拆分JavaScript文件,即需即载入即运行,避免首次载入的高代价。类似dojo的分包机制。 普通的script会阻塞页面的载入直至脚本下载执行完成,采用其它方法可以改变这种情况:XHR Evel, XHR Inject, Script DOM, Script Defer, Script in Iframe, Document.write Script Tag。 由于外部script和内联代码异步载入造成的冲突,解决方法1. 在外部编码种硬编码回调,2. 在Window.onload中调用 3. 用timer监控载入情况 4.scripttag.onreadystatechange 把异步载入外部脚本的方法编写为可复用的module 处理内联脚本,解决方法:1.将内联脚本移至页面尾部 2.异步执行JavaScript回调(setTimeout(0)) 3.使用script defer属性 内联脚本执行会被 语言级别上提高JavaScript执行效率的一些手段,Zakas Comet的前景和现阶段实现,以及WebSocket 优化HTML文件 优化图片的utilities和几种格式的特点 sharding文件到不同的服务器上增加并行下载 正确地使用flush提高部分页面的加载速度 影响因素1.是否开启了Output_Buffer,2.是否使用了chunked encoding, 3.是否启用了gzip并在apache228上运行 4. 是否被代理和AV软件影响了 5.是否因为相同的域名的文件下载被block了 6.是否是webkit阈值以下不能渲染 慎用iframe,DOM操作代价过高,在html中设置src的iframe会阻塞onload,iframe与style script标签的位置 高性能的CSS选择器,避免全局rule,避免div#sele,避免div.sele,避免使用长选择器,避免使用decendant选择器,避免使用tag-child选择器,查看所有child选择器,使用继承
Published at: 04:07 pm - Saturday July 18 2009
OSM(http://www.osm.org) has released their first prototype of static map api. It is aimed to make web mapping easier to refer just like google has done. All interfaces are listed in following page: http://dev.openstreetmap.org/~pafciu17/ With OSM static api, you can: Show a map centered at a specified point. (using center, height and width) Show a map [...]
Published at: 09:07 pm - Thursday July 02 2009
All scripts created by paster(paster create, paster controller and etc.) uses 4 spaces as indent while many editors(vim) uses tabs automatically. Different indent in one file will cause fatal error. h.url_for is a popular helper function in many books and tutorials which to solve url mapping. This tool is no longer available by default since [...]