概述
有道云笔记旨在以云存储技术帮助用户建立一个可以轻松访问、安全存储的云笔记空间,解决了个人资料和信息跨平台跨地点的管理问题,目前已经提供了桌面版、网页版以及部分手机型号的版本。但是用户对笔记的需求不仅仅局限于这几种情形,对于很多非笔记应用,用户仍然可能有跨平台跨设备的存储需求。通过开放的API,第三方应用只需要进行简单的开发,就可以通过标准的web协议对有道云笔记的数据进行安全的访问与修改,而不需要搭设和维护运存储服务,这大大降低了第三方的开发与运营成本,从而将更多的精力专注于应用本身。
本文档从技术角度对有道云笔记的开放API进行说明,从而方便开发者的理解和使用。
数据模型
目前有道云笔记的数据模型包括用户、笔记本、笔记以及附件四部分,下面将对它们分别进行说明:
用户
每一个有道云笔记的账号(目前我们使用网易通行证作为账号,但是以后将允许使用其它网站的开放认证账号,例如新浪微博账号,人人网账号)都在系统中对应着一份用户信息,包括该用户邮箱、笔记总空间、当前使用空间、默认笔记本、在线时间以及注册时间上次修改时间等一系列信息。
笔记本
用户通过笔记本对所有笔记进行组织管理,每一篇笔记必须属于某一个笔记本,同时为了方便用户的区分与定位,每个笔记本也必须具有唯一的名字。目前有道云笔记仅支持一层笔记本结构,而不支持笔记本的多层嵌套。
对于同一篇笔记,可以在两个笔记本之间进行转移,但是却不允许出现在两个笔记本中。此外,每个用户在任何时候都有一个笔记本被标记为默认笔记本,如果一个笔记在创建时没有特别指明笔记本,它将被放入默认笔记本中。删除一个笔记本将删除该笔记本下的所有笔记。
虽然有道云笔记的客户端同时提供了同步笔记本与本地笔记本两种类型,但是由于本地笔记本仅存储在用户的本机而没有上传至服务器,因此开放API只能创建或者访问用户同步笔记本中的笔记。
笔记
一篇笔记由一段超文本以及相关联的附件(例如图片、文本、PPT、PDF等)所组成,其中超文本的内容按照一种标记语言的格式进行存储,每个附件所在的位置都对应着一个tag,包含着该附件路径,从而可以根据该信息找到对应附件的数据。同时,每个笔记还包含一些属性信息,例如题目、作者、来源URL以及创建修改时间等,这些信息可以用来对笔记进行查找、过滤以及排序。
当一个笔记被删除时,它将被放入回收站,回收站中的笔记在一定的时间内仍然可以访问(Open API不可以访问删除的笔记),但是不可以进行编辑,如果没有进行恢复,回收站的笔记将在一定的时间后(目前为两个月)被清除。
笔记标记语言格式的详细说明见附录A。
附件
笔记附件是附属于笔记的二进制数据,无法脱离笔记单独存在,因此如果仅上传附件而不添加相应的笔记,则该附件会被定期的空间回收所删除。笔记附件类似于邮件的附件,但是与邮件的附件不同的是,笔记的附件没有与笔记的内容进行整体编码,而只是在笔记内容超文本的对应位置放置了一个tag,附件的数据则单独进行存储。因此如果将附件tag在两个笔记之间进行拷贝,这两个笔记将共享同一个附件,而对附件的修改也将同时反映在两个笔记之中。不过目前我们尚不提供附件修改的API,还不存在这样的问题。随着API的晚上,以后将提供类似的API,因此如果第三方应用希望避免这种情况,需要自行对附件拷贝进行处理。另一方面,如果共享附件的两篇笔记中有一篇笔记被删除,不会对另外一篇笔记及其附件造成影响。
目前笔记的附件支持除了exe、com、cmd、bat、sys以外的所有文件格式,大小限制为25MB。
授权机制
为了对用户的数据进行保护,大部分API的访问都需要获得用户的身份信息,我们采用OAuth的方式对第三方应用进行授权,只有经过用户授权的应用才可以对用户的数据进行访问。目前我们支持OAuth 1.0a,OAuth的官方技术说明可参看 http:///core/1.0a。
申请Consumer Key
对于所有需要使用Open API的应用,在使用Open API之前首先要在系统内申请一个应用程序,申请者需要提交申请人姓名、应用名称、callback URL以及是否限制callbackURL等信息,我们会生成相应的ConsumerKey和ConsumerSecret,作为每个应用的身份标识。应用名称和ConsumerKey在系统中均是唯一的,在进行请求时,第三方应用需要将ConsumerKey加入请求中,而系统收到请求后,便可以根据ConsumerKey和ConsumerSecret对请求进行验证与记录。
请求用户授权
授权流程
在拿到ConsumerKey和ConsumerSecret以后,应用程序便可以结合ConsumerKey申请一个request_token和request_secret,发送的内容应该有ConsumerSecret的签名。
应用程序再次用request_token和ConsumerKey来申请用户授权。该请求内容应该由ConsumerSecret和request_secret共同签名。授权时,需要用户在OauthServer提供的页面中输入用户名密码等信息进行授权操作,已经登录过的用户可以直接进行授权操作。用户授权之后,会返回request_token和verifier. 此时的request_token在OauthServer中已经授权。
授权之后,应用程序就可以使用request_token申请access_token和access_secret。该请求内容同样要使用ConsumerSecret和request_secret共同签名。
如果以上步骤中可能会因为超时或者发送内容不符造成错误。OAuth会返回错误信息给应用程序。
详细流程见图2.1.1,

图2.1.1 授权流程图
授权请求参数方法和返回值
下面将介绍如何使用OauthServer服务得到access_token和access_secret。下面的文字中[baseURL]指代OauthServer的URL。对于线上环境,该baseURL即为http://note.youdao.com/,而对于sandbox测试环境,该baseURL为http://sandbox.note.youdao.com/。这里使用HTTP Header设置参数: Header name设为 Authorization,Header value设为OAuth[空格][parameterName=”value”],[空格][ parameterName=”value”]… 。 值得注意的是parameterName和value必须进行URL编码,并且在URL编码后还要将”+”替换为”%20”,将”*”替换为”%2A”,将”%7E”替换为”~”。例如请求authorized token时 HTTP header中的value是:
OAuth[空格]oauth_token="29cc36314495ee1cf55ebf26ca9711bc",[空格] oauth_consumer_key="407d014e17ad5cd02f3e0a55fcb198af", [空格]oauth_signature_method="HMAC-SHA1",[空格]oauth_timestamp="1323325710",[空格]oauth_nonce="278825208972307",[空格]oauth_version="1.0",[空格] oauth_signature="x8E7wrAmn6GyHv4aldWSo1M2ShU%3D"。 注意,其中双引号””是必须的。 发送请求时,这些参数可以是无序的。但是签名时这些参数有一定的顺序。详见附录D
以下各个请求正确时,返回值content-type为text/plain. 返回key=value[空格]key=value
以下各个请求错误时,会返回错误信息。该信息包含error, message等。error是错误码,message包含更详尽的错误信息。另外特殊错误时还可能返回更多信息。详见附录B。
请求request_token
l URL:[baseURL]/oauth/request_token
l 请求方式:GET
l 请求参数:
参数名 |
参数说明 |
oauth_callback |
回调url,该url可以为oob,代表不回调。另外url还可以跟其他参数 |
oauth_consumer_key |
申请应用时拿到的consumerKey |
oauth_signature_method |
签名方法,支持HMAC-SHA1 |
oauth_timestamp |
时间戳,当前时间,单位毫秒 |
oauth_nonce |
随机串,为了防止重放攻击,5分钟内同一用户同一应用同一时间发来的请求中oauth_nonce应不同 |
oauth_version |
1.0 |
oauth_signature |
签名,使用consumerSecret +’&’作为签名的key, 而签名的内容是除oath_signature以外的请求url内容,计算签名完毕后,使用base64编码 |
l 正确时返回:oauth_token_secret(授权流程中的request_secret用于申请access_token时签名) 、oauth_token(授权流程中的requset_token用于authorize请求和access_token请求)和 oauth_callback_confirmed(boolean值)
l 错误时返回: error, message. error是error code. message是错误信息。以json串形式返回。
l 发送示例:
用curl来举例, 请求信息类似于
curl –H “Authorization: OAuth oauth_callback=\”oob\”, oauth_consumer_key=\”7a23b1eaf487060deaa5660b323c341b\”, oauth_signature_method=\”HMAC-SHA1\”, oauth_timestamp=\”1321847131\”, oauth_nonce=\”439563436203139\”, oauth_version=\”1.0\”” “http://sandbox.note.youdao.com/oauth/request_token”
但是需要注意的是各个key-value对都需要使用OAuth编码, 详见附录D
l 备注:
示例中的签名内容大致为(参数顺序可能有变化,详见附录D的签名过程):
GET& http://sandbox.note.youdao.com/oauth/request_token&oauth_callback=oob&oauth_consumer_key=7a23b1eaf487060deaa5660b323c341b&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1321847131&oauth_nonce=439563436203139&oauth_version=1.0
具体签名方法详见附录D.
请求授权
l URL: [baseURL]/oauth/authorize
l 请求方式:GET
l 请求参数:该处的参数必须以query string的形式发送
参数名 |
参数说明 |
oauth_token |
请求request_token时返回的oauth_token |
l 正确时返回:oauth_token(授权后的request_token) 和oauth_verifier
l 错误时返回:error, message
l 发送示例:
GET http:// sandbox.note.youdao.com/oauth/authorize?oauth_token=5420db084cc41d768d885a53f7b2c1a6
l 备注:如果oauth_callback为oob,则不会回调。用户会在Oauth Server页面上看到pin码。用户需要手工将pin码粘帖到application中才能申请到AccessToken。应用请求authorize时,如果请求携带了网易或者有道的cookie, 则将直接询问用户是否授权。否则会重新定向到网易的通行证页面。
请求access_token
l URL:[baseURL]/oauth/access_token
l 请求方式:GET
l 请求参数:
参数名 |
参数说明 |
oauth_consumer_key |
回调url |
oauth_token |
request_token时返回的oauth_token |
oauth_verifier |
Authorize请求时发送回来的oauth_verifier,或者是OauthServer页面显示的Pin码 |
oauth_signature_method |
签名方法,支持HMAC-SHA1 |
oauth_timestamp |
时间戳,当前时间,单位毫秒 |
oauth_nonce |
随机串,为了防止重放攻击,5分钟内同一用户同一应用同一时间发来的请求中oauth_nonce应不同 |
oauth_version |
1.0 |
oauth_signature |
使用consumerSecret + ’&’ + oauth_token_secret字串作为key, 而签名的内容是除oauth_signature以外的请求url内容,计算签名完毕后,使用base64编码 |
l 正确时返回:oauth_token_secret (授权流程中的access_secret)、oauth_token (授权流程中的access_token)
l 错误时返回:error, message
l 发送示例: http header的例子
curl –H “Authorization: OAuth oauth_verifier=\”8714fb943a28d7faffec3265e96d85cd\”, oauth_token=\”b348d10a0f45a4cf6936381d6c9fb00f\”, oauth_consumer_key=\”7a23b1eaf487060deaa5660b323c341b\”, oauth_signature_method=\”HMAC-SHA1\”, oauth_timestamp=\”1321857128\”, oauth_nonce=\”449560105422526\”, oauth_version=\”1.0\”, oauth_signature=\”S8yxdpLIA7MiFVDE4OzSDoo%2F6%2FI%3D\”” “http://sandbox.note.youdao.com/oauth/access_token”
访问OpenAPI
由2.2.3返回的oauth_token将用于OpenAPI的请求, consumerSecret + ’&’ + oauth_token_secret将用作签名。例如请求创建笔记本 http://[baseURL]/yws/open/notebook/create.json,则应在请求创建笔记中添加各种参数(创建笔记本的其他参数按文档要求不变),如果没有,则会返回error和message(此处的error和message会放入到json串中,error是错误码, message是具体错误信息),不会执行任何OpenAPI操作。
例如执行创建笔记本操作。参数name,需和oauth的其他值一起进行签名。但是不应该将name放入header中。并且发送post请求的Content-Type为application/x-www-form-urlencoded。其他参数填入http content域。Oauth参数放入Authorization Header域。否则可能会出现错误。
对于上传笔记或者附件图片的open API中。post请求的Content-Type为multipart/form-data。非oauth参数均不参与签名。非oauth参数填入http content域。Oauth参数放入Authorization Header域。否则可能会出现错误。
对于使用GET请求http://[baseURL]/yws/open/user/get.json,需要将oauth参数和非oauth参数一起放入url参数中。签名时需注意参数顺序。发送请求时参数可以无序。
POST
http://note.youdao.com/yws/open/note/create.json
Header 中Authorization的值为
OAuth[空格]oauth_token="29cc36314495ee1cf55ebf26ca9711bc", oauth_consumer_key="407d014e17ad5cd02f3e0a55fcb198af", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1323327110", oauth_nonce="280224628487931", oauth_version="1.0", oauth_signature="rXpd0apk82wMAZLun%2FDSUt1wbQE%3D"
最终Header类似于:
Authorization=OAuth%20oauth_token%3D%2229cc36314495ee1cf55ebf26ca9711bc%22%2C%20oauth_consumer_key%3D%22407d014e17ad5cd02f3e0a55fcb198af%22%2C%20oauth_signature_method%3D%22HMAC-SHA1%22%2C%20oauth_timestamp%3D%221323327041%22%2C%20oauth_nonce%3D%22280155519121203%22%2C%20oauth_version%3D%221.0%22%2C%20oauth_signature%3D%22E%252F8dFmTFGTmdCFE2rnJ8f%252Bkzw9c%253D%22
签名的具体方法详见附录D,访问Oauth的类库包详见附录C。
用户操作API
查看用户信息
l URL:http://[baseurl]/yws/open/user/get
l 请求方式:GET
l 支持格式:JSON
l 是否需要用户认证:是 (关于登录授权,参见
l 请求参数:无 l 返回结果:操作成功时http状态为200,并用户信息;失败时http状态为500并返回错误码和错误信息,详见附录B。 结果示例: { “user” : “test@163.com”, // 用户ID “total_size” : “10293736383”, // 用户总的空间大小,单位字节 “used_size” : “1024” // 用户已经使用了的空间大小,单位字节 “register_time” : “1323310917650” // 用户注册时间,单位毫秒 “last_login_time” : “1323310949120” // 用户最后登录时间,单位毫秒 “last_modify_time” : “1323310978120” // 用户最后修改时间,单位毫秒 “default_notebook” : “/AB384D734” // 该应用的默认笔记本 } 注:对于每个第三方应用,都分别在用户的笔记空间中对应一个默认笔记本,笔记本名在申请应用时指定,在使用OpenAPI创建笔记时,如果第三方应用不指定笔记本,则自动创建在该默认笔记本中。 l URL:http://[baseurl]/yws/open/notebook/all l 请求方式:POST l Content-Type:application/x-www-form-urlencoded l 支持格式:JSON l 是否需要用户认证:是 (关于登录授权,参见
l 请求参数:无 l 返回结果:操作成功时http状态为200,并返回笔记本列表;失败时http状态为500并返回错误码和错误信息,详见附录B。 结果示例: [ {“path” : “/4AF64012E9864C”, // 笔记本的路径 “name” : “笔记本1”, // 笔记本的名称 “notes_num” : “3” // 该笔记本中笔记的数目 “create_time” : “1323310917” // 笔记本的创建时间,单位秒 “modify_time” : “1323310949” // 笔记本的最后修改时间,单位秒 }, {“path” : “/5AB0C6B33BD1162”, “name” : “笔记本2”, “notes_num” : “10” “create_time” : “1323311244” “modify_time”: “1323310349” } ] l URL:http://[baseurl]/yws/open/notebook/list l 请求方式:POST l Content-Type:application/x-www-form-urlencoded l 支持格式:JSON l 是否需要用户认证:是 (关于登录授权,参见
l 请求参数: 参数名 参数说明 是否必须 数据类型/限制 notebook 笔记本路径 是 String l 返回结果:操作成功时http状态为200,并返回该笔记本下的笔记列表(只有笔记路径,笔记内容需要通过笔记接口获取);失败时http状态500并返回错误码和错误信息,详见附录B。 结果示例: [ “/4AF64012E9864C/123TDE3DC”, // 笔记路径 “/4AF64012E9864C/DC12FTDE3”, “/4AF64012E9864C/FE23TDE3C” ] l URL: http://[baseURL]/yws/open/notebook/create.json l 请求方式:POST l Content-Type:application/x-www-form-urlencoded l 支持格式:JSON l 是否需要用户认证:是 (关于登录授权,参见
l 请求参数: 参数名 参数说明 是否必须 数据类型/限制 name 笔记本名称 是 String l 返回结果:操作成功时http状态200,并返回新创建笔记本的路径;失败时http状态500并返回错误码和错误信息,详见附录B。 结果示例: {“path” : “/4AF64012E9864C”} l URL: http://[baseURL]/yws/open/notebook/delete.json l 请求方式:POST l Content-Type:application/x-www-form-urlencoded l 支持格式:JSON l 是否需要用户认证:是 (关于登录授权,参见
l 请求参数: 参数名 参数说明 是否必须 数据类型/限制 notebook 笔记本路径 是 String l 返回结果:操作成功时http状态200,无返回数据;失败时http状态500并返回错误码和错误信息,详见附录B。 l URL: http://[baseURL]/yws/open/note/create.json l 请求方式:POST l Content-Type:multipart/form-data l 支持格式:JSON l 是否需要用户认证:是 (关于登录授权,参见
l 请求参数: 参数名 参数说明 是否必须 数据类型/限制 source 笔记来源URL 否 String author 笔记作者 否 String title 笔记标题 否 String content 笔记正文(笔记格式见附录A) 是 String notebook 该新建笔记所属的笔记本路径 否 String l 返回结果:操作成功时http状态为200,并返回新建笔记的路径;失败时http状态为500并返回错误码和错误信息,详见附录B。 结果示例: {“path” : “/4AF64012E9864C/FE89D12134E”} 注:如果第三方应用没有指定notebook,则在该第三方应用对应的默认笔记本中创建该笔记。 l URL: http://[baseURL]/yws/open/note/get.json l 请求方式:POST l Content-Type:application/x-www-form-urlencoded l 支持格式:JSON l 是否需要用户认证:是 (关于登录授权,参见
l 请求参数: 参数名 参数说明 是否必须 数据类型/限制 path 笔记路径 是 String l 返回结果:操作成功时http状态为200,并返回该笔记的相关信息;失败时http状态为500并返回错误码和错误信息,详见附录B。 结果示例: { “title” : “工作记录”, // 笔记标题 “author” : “Tom”, // 笔记作者 “source” : “http://note.youdao.com”, // 笔记来源URL “size” : “1024”, // 笔记大小,包括笔记正文及附件 “create_time” : “1323310917” // 笔记的创建时间,单位秒 “modify_time” : “1323310949” // 笔记的最后修改时间,单位秒 “content” : “<p>This is a test note</p> // 笔记正文 } l URL: http://[baseURL]/yws/open/note/update.json l 请求方式:POST l Content-Type:multipart/form-data l 支持格式:JSON l 是否需要用户认证:是 (关于登录授权,参见
l 请求参数: 参数名 参数说明 是否必须 数据类型/限制 path 修改笔记的路径 是 String source 修改后的笔记来源URL 否 String author 修改后的笔记作者 否 String title 修改后的笔记标题 否 String content 修改后的笔记正文(笔记格式见附录A) 是 String l 返回结果:操作成功时http状态为200,无返回结果;失败时http状态为500并返回错误码和错误信息,详见附录B。 l URL: http://[baseURL]/yws/open/note/move.json l 请求方式:POST l Content-Type:application/x-www-form-urlencoded l 支持格式:JSON l 是否需要用户认证:是 (关于登录授权,参见
l 请求参数: 参数名 参数说明 是否必须 数据类型/限制 path 想要移动的笔记原路径 是 String notebook 目标笔记本的路径 是 String l 返回结果:操作成功时http状态为200,返回移动后的笔记路径;失败时http状态为500并返回错误码和错误信息,详见附录B。 结果示例: {“path”: “/5AB0C6B33BD1162/FE89D12134E”} l URL: http://[baseURL]/yws/open/note/delete.json l 请求方式:POST l Content-Type:application/x-www-form-urlencoded l 支持格式:JSON l 是否需要用户认证:是 (关于登录授权,参见
l 请求参数: 参数名 参数说明 是否必须 数据类型/限制 path 想要删除的笔记原路径 是 String l 返回结果:操作成功时http状态为200,无返回结果;失败时http状态为500并返回错误码和错误信息,详见附录B。 l URL:http://[baseurl]/yws/open/resource/upload l 请求方式:POST l Content-Type:multipart/form-data l 支持格式:JSON l 是否需要用户认证:是 (关于登录授权,参见
l 请求参数: 参数名 参数说明 是否必须 数据类型/限制 file 上传的附件文件(包括附件的文件名、类型、大小、数据等) 是 Multipart File/附件大小限制25M l 返回结果:操作成功时http状态为200,对于图片,返回该图片的链接URL,对于普通附件,服务器会为该附件生成一个图标文件,因此返回结果包括该附件对应的链接URL以及图标的URL;失败时http状态为500并返回错误码和错误信息,详见附录B。 示例: 图片附件 {"url" : "http://baseURL/yws/open/resource/28/d83f547f3055"} 普通附件 { "url" : "http://baseURL/yws/open/resource/28/d83f547f3055" // 附件URL "src": " http://baseURL/yws/open/resource/29/7f2bd6fa2795" // 图标URL } 需要注意的是,在附件上传完成后,使用者应该紧接着更新对应的笔记,否则不被任何笔记引用的附件将被定期的空间回收所删除。 l URL:http://[baseURL]/yws/open/resource/download/... l 请求方式:GET l 是否需要用户认证:是 (关于登录授权,参见
l 返回结果:操作成功时,response返回附件及图片的二进制流;失败时http状态为500并返回错误码和错误信息,详见附录B。 l 备注: 1.当打开笔记时,对于笔记中的附件及图片链接,只需要添加用户的OAuth认证信息即可以获取对应的附件及图片,同理在上传附件后,返回的附件及图片链接也可以通过这种方式进行访问。 2.附件及图片的下载支持断点续传 笔记内容的格式采用类HTML的标记语言,绝大部分格式相关tag均采用标准的HTML Tag,唯一需要不同的是附件及图片Tag。在格式上图片Tag与标准的img tag相同,一个图片资源的标记如下: <img src="http://note.youdao.com/yws/open/resource/22/7f2bd6fa2795441c"> 但是由于对应的接口需要用户认证,因此在获取图片资源时,需要加入OAuth的用户认证信息。 附件通常以图标在笔记中进行显示,因此我们扩展了图片Tag <img>,除了img本身的src属性,额外加入了一个属性path,其中src对应着该附件的图标URL,而path则为该附件的URL,如下所示: <img path="http://note.youdao.com/yws/open/resource/21/9fe604c7c90642fd8f" src="http://note.youdao.com/yws/open/resource/22/7f2bd6fa2795441c"> 同理,也需要加入OAuth的用户认证信息,才可以正常访问附件资源及其图标。 同理,当Open API的请求在执行时出现任何异常或错误时,系统将返回Http 500,应用程序可以根据此判断请求是否成功执行。当应用程序在进行OAuth认证,或者未经认证便调用Open API时,系统会返回OAuth错误信息,OAuth的错误码与错误信息将以json的格式进行返回,各个错误码及错误信息说明如下: 错误码 错误描述及可能原因 1001 token_rejected:consumer没有找到,consumerKey错误, consumer没有创建,或者request token或者access token 不存在于server中,或者没有获得授权的token,或者token过期 1002 parameter_rejected:这个会返回具体原因key是oauth_parameters_rejected, value是一个parameter列表 1003 version_rejected:OAuth版本号不是1.0 1004 timestamp_refused:timestamp 非5分钟内 1005 nonce_used:5分钟内该nonce被使用 1006 parameter_absent:有些参数没有发送给server 1007 signature_invalid:oauth签名异常,可能原因没有签名,签名方法和签名不一致等 1008 signature_method_rejected:oauth server没有提供该签名方法 1009 access_state_error:获取token时状态混乱,详细的信息会告知当前的状态 [AUTHORIZED | REQUEST | ACCESS | INVALID] 1010 consumer_rejected:该consumer在server中不存在,或者被禁掉。或者consumerKey改变,但是还没有反应到server的数据库中。 1011 accessor_rejected:由token得到的accessor构造异常,或者accessor中缺失某些属性,或者转换失败 1012 callback_error:request token传来的callback和以后的callback不一致。 1013 callback_domain_error:当限定callback后,发来的callback与原设置的callback的域不相同 1014 verifier_error:Verifier不一致错误 1015 permission_denied:无授权的token,或者授权后没有获取过access token 同理,当Open API的请求在后台执行出现异常或错误时,系统也将同时错误码与错误信息以json的格式一同返回,应用程序可以根据错误码得到相应的原因,常见的错误码说明如下: 错误码 错误描述及可能原因 206 UNKNOWN_URI:错误的URI请求 207 AUTHENTICATION_FAILURE:用户认证错误 209 RESOURCE_NOT_EXIST:请求的资源(笔记本、笔记、附件等)不存在 210 USER_SPACE_FULL:用户空间已满 214 INVALID_PARAMETER:错误的传入参数,必须的参数为空等 220 USER_NOT_EXISTS:用户不存在 221 USER_ALREADY_EXISTS:用户已经存在,不能重复注册 225 PARENT_NOT_EXIST:笔记本尚不存在,不能在该笔记本下创建笔记 231 RESOURCE_ALREADY_EXIST:该笔记或者附件已经存在,不能重复创建 304 NOTE_ALREADY_DELETED:笔记已经被删除 307 INVALID_APPLICATION:无效的第三方应用,未经过用户授权或者授权失败便通过OpenAPI访问用户数据.这个一般是使用测试环境得到了access_token,利用该access_token访问了线上环境。这两套环境是独立的。Access_token不能共用。 但是如果第三方应用未经过用户授权 示例:当查看笔记路径错误时 { "error" : "209", "message" : " Required note does not exist, path=/5AB0C6B33BD12/FE89D12134E" } ActionScript/Flash oauth-as3 http://code.google.com/p/oauth-as3/ A flex oauth client http://www./home/item.html?id=ff6ffa302ad04a7194999f2ad08250d7 C/C++ QTweetLib http://github.com/minimoog/QTweetLib libOAuth http://liboauth./ clojure clj-oauth http://github.com/mattrepl/clj-oauth .net oauth-dot-net http://code.google.com/p/oauth-dot-net/ DotNetOpenAuth http://www./ Erlang erlang-oauth http://github.com/tim/erlang-oauth java Scrible http://github.com/fernandezpablo85/scribe-java oauth-signpost http://code.google.com/p/oauth-signpost/ javascript oauth in js http://oauth./svn/code/javascript/ Objective-C/Cocoa & iPhone programming OAuthCore http:///atebits/oauthcore MPOAuthConnection http://code.google.com/p/mpoauthconnection/ Objective-C OAuth http://oauth./svn/code/obj-c/ Perl Net::OAuth http://oauth./svn/code/perl/ PHP tmhOAuth http://github.com/themattharris/tmhOAuth oauth-php http://code.google.com/p/oauth-php/ Python python-oauth2 http://github.com/brosner/python-oauth2 Qt qOauth http://github.com/ayoy/qoauth Ruby Oauth ruby gem http://oauth./ Scala DataBinder Dispatch http://dispatch./About 1. 加密内容是: a. 请求方法名,例如 GET, POST等. 加密时方法名大写并进行特殊替换(详见3)。 b. url (query param之前的部分,不包括 ?),Http或者https需要全部小写, http如果带有80端口,或者https带有443端口,需要将其省略。其他端口则不能省略。例如: Http://local:9999/requestToken e http://local:9999/requestToken e http://local:9999/requestToken e https://local /requestToken c. 参数(query param中的或者header中的key-value对), 首先将这些参数进行特殊替换后,按字典序排序升序排列。如果两个key相同,则以value特殊替换后字典序为准。key与value之间使用”=”连接,如果value==null,则使用””替代。两个参数对之间使用”&”连接。连接后形成的最终字符串的开头和结尾没有”&”. d. 字典序字符串比较大小伪代码: Int compare(string a, string b) { Int min_len = min(len(a), len(b)) For I to min_len { If (a[i] != b[i]){ Return a[i] – b[i] } } Return len(a) – len(b) } 将以上a,b,c三部分进行特殊替换后,使用&连接。最终形成的字符串的开头和结尾都没有”&”。这就是加密内容。 2. 加密的key是consumerSecret + & + TokenSecret, 如果TokenSecret还没有得到,则使用””。 consumerSecret和TokenSecret需先做特殊替换,然后再进行签名。 3. 特殊替换是将String进行URL编码后,将”+”替换为”%20”,将”*”替换为”%2A”,将”%7E”替换为”~”. 4. 签名方法可以使用HMAC-SHA1,PLAINTEXT, RSA_SHA1三种。其中PLAINTEXT为2中的key. 该方法不提倡使用。 得到签名内容后使用Base64进行编码。编码后的字符串即为oauth_signature.笔记本操作API
查看用户全部笔记本
列出笔记本下的笔记
创建笔记本
删除笔记本
笔记操作API
创建笔记
查看笔记
修改笔记
移动笔记
删除笔记
附件操作API
上传附件或图片
下载附件/图片/图标
附录A:有道云笔记内容格式
附录B:错误码及错误信息说明
附录C: 访问OAuth Server的类库与包
附录D: Oauth签名加密oauth_signature