• RAILS API TO BE PART OF RAILS 5 at 2015年06月30日

    @reyesyang github 上, master 分支已经拥有 rails api 了, 但 4.2-stable 是木有的.

  • @bpw11320

    密码那一段是让你换一个思路思考这个请求的结构, 并非推荐你这样做. 使用这种结构的原因是因为你设计 Public API 的时候需要是 "无状态" .

    总的来说建议你思考清楚两个问题:

    1. 无状态是什么? (HTTP, Public API)
    2. token 的作用是什么, 为什么要用 Token 而非用户名密码? (多想想除了显而易见的 "减少账户密码的曝光" 还有什么其他原因?, 因为传输过程中的数据使用 SSL 基本无法截取到有效明文)

    多想想再找找资料, 设身处地的想想, 如果你设计这个东西会怎么设计?

  • RAILS API TO BE PART OF RAILS 5 at 2015年06月29日

    就等 rails 5 发布, 后端改到 rails --api 前端 Ember.js 已经磨刀霍霍了~

    @dy1901 所以前端的 load balance 是个好东西, newrelic 也是个好东西. 有数据, 你才知道何时要怎么处理什么问题.

  • 你不应该将提交用户 id 信息暴露给互联网.

    "用户删除他的车辆" 的 Public API 可以考虑仅仅设计一个参数 "car_id" 同时应该为 DELETE 提交(至少为 POST), 因为

    • 哪个用户在执行操作, 通过 token 信息告诉你
    • 用户要删除 card 的功能, 通过设计好的具体 API 地址信息告诉你
    • 用户对资源的删除操作, 通过 Restful 中的 DELET 信息告诉你
    • 最后用户要操作的是哪一个具体 "资源" , 则需要通过用户主动输入的 参数 id 告诉你.

    另外 token 一定是需要与哪一个用户绑定, 如果 token 不与用户绑定, 那整个网站的操作不久乱了, 一个 token 所有用户的"资料"都可操作. Public API 应该设计为 state less 的, 并且避免使用 cookie 来协助保存用户状态. 每一次的 API 调用都应该携带上与某一个用户关联的有时效性的 token.

    可以把这个 token 的概念联想一下

    • 每一次的 API 请求都带上 username 与 password.
    • 用户的 username 与 password 都是存储在数据库.
    • 通过 username 与 password 去寻找唯一的用户, 所有的资源都与某一个用户相关, 只能操作自己的资源.

    此问题想远一点会扩展到另外一个 Web 安全的话题: CSRF 通过 token 的方式来进行 API 验证的时候, 对于 CSRF 的预防就好比"用户登陆网站", 对于用户账户密码信息被盗的预防(对用户 Token 被盗的预防).

  • :thumbsup:

    现在直接使用 Ember 1.13 stable ~ 然后直接升级 Ember 2.0 stable

  • #6楼 @huacnlee 这个问题是这样的.

    ?limit=100 的时候

    ?limit=101 的时候

    我也比较奇怪为啥是这样 - -||

  • #1楼 @liuhui998 啥时候你也分享点经验

    #2楼 @aidewoode 我考虑了一下, 感觉如果是纯 JS 客户端要去实现 Oauth2 其实可行, 就是还会有一些不安全因素在, 因为所有信息都是公开的, 所以就放弃了... 还是要拥有一个后端合适一点.

  • @hanji @huacnlee 貌似我现在也不行了... 返回 是使用 "urn:ietf:wg:oauth:2.0:oob" 注册的登陆回掉地址.

    {"error":"invalid_grant","error_description":"登录回调地址无效、过期或者已经被撤销了"}
    
  • @hanji 有进行"注册应用"吗?

  • @hanji

    使用 curl 获取: curl -X POST -d "grant_type=password" -d "username=[name]" -d "password=[pass]" 'https://ruby-china.org/oauth/token'

    * Adding handle: conn: 0x7fd1b280aa00
    * Adding handle: send: 0
    * Adding handle: recv: 0
    * Curl_addHandleToPipeline: length: 1
    * - Conn 0 (0x7fd1b280aa00) send_pipe: 1, recv_pipe: 0
    * About to connect() to ruby-china.org port 443 (#0)
    *   Trying 61.174.15.167...
    * Connected to ruby-china.org (61.174.15.167) port 443 (#0)
    * TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
    * Server certificate: www.ruby-china.org
    * Server certificate: StartCom Class 1 Primary Intermediate Server CA
    * Server certificate: StartCom Certification Authority
    > POST /oauth/token HTTP/1.1
    > User-Agent: curl/7.30.0
    > Host: ruby-china.org
    > Accept: */*
    > Content-Length: 70
    > Content-Type: application/x-www-form-urlencoded
    >
    * upload completely sent off: 70 out of 70 bytes
    < HTTP/1.1 200 OK
    * Server nginx/1.8.0 is not blacklisted
    < Server: nginx/1.8.0
    < Date: Thu, 04 Jun 2015 05:13:35 GMT
    < Content-Type: application/json; charset=utf-8
    < Transfer-Encoding: chunked
    < Connection: keep-alive
    < Strict-Transport-Security: max-age=31536000
    < X-Frame-Options: SAMEORIGIN
    < X-XSS-Protection: 1; mode=block
    < X-Content-Type-Options: nosniff
    < Cache-Control: no-store
    < Pragma: no-cache
    < ETag: W/"5275890161f17844e4dffefe6e643344"
    < X-Request-Id: 9d8e536c-3fb6-456e-a3b1-8f88a9799a77
    < X-Runtime: 0.296195
    <
    * Connection #0 to host ruby-china.org left intact
    {"access_token":"xxxxxxxx","token_type":"bearer","expires_in":86400,"refresh_token":"xxxxxxxxxx","created_at":1433394815}
    
  • 很少进行 Ruby 代码的 Debug, 一般跑测试验证.

  • @aidewoode 如果需要在 /posts/1 的页面里面查看 post 和分页的 comments 你的 URL 应该需要 /posts/1/comments?page=N 这种形式了

    这样你的 Router 就是你上面写的那样, 而同时你需要手动准备

    • PostsCommentsRouter : 在这个里面准备你关于某个 post 的 comments 数据
    • PostsCommentsController : 在这里准备 template 里面的事件和需要收集的参数.
    • template/posts/comments.hbs : 这个与对应的 controller 对应使用.

    这样设计 API 可能有点怪怪的, 例如: 你查看 topic 的 comments 理想的是 /topic/1 查看 topic 和这个 topic 的 comments, 要查看分页的 comments 会是 /topic/1?page=2 这样.

    我说区分 front 和 backend 的意思是, 其实 Ember 提供 双向绑定 的好处就是, 你可以不用理睬 template 改如何展示你的 model 数据, 因为 Ember 让你的数据在前端是"活"的, 只要 Ember 所绑定的 data/model 发生变化 template 就会自动的变化, 而这个思维与 backend 中的数据变化则一定需要重新 get 一个页面不太一样.

    另外, 我猜测你应该还是使用了 Ember-Data, 而 Ember-Data 中对于分页功能现在还没有尘埃落定(我们看起来简单, 实现起来还是有他们的难度) 参看两个 issue #1517 #2095 所以现在的意思就是, 如果我们要做分页, 还得自己想想办法, 当渲染了 posts 后, 在 PostsController 或者 PostsRouter 中自己再重新提交请求向 backend 要分页的 comments 数据, 再 push 到 store 中让 Ember 自动处理变化的数据. (你会发现 Discourse 的分页取巧了, 给了总个数, 但没有给页码, 而且是一直拖拽加载不是分页加载. 当然这种形式也挺适合他们的需求)

  • 你得区分一下 front 和 backend. 前端是不同的页面通过 route 在跳转, 而在 ember router 中准备数据. 你可以这样思考:

    1. PostRouter 中就加载好 posts 的第一页的 comments
    2. 写好 template 然后利用 {{render}} 传入 model
    3. 分页的操作在按照道理应该在 PostRouter 中的 actions 处理, 远程加载数据.

    {{render}} helper 的特点在文档中有写:

    {{render}} does several things:
    
    * When no model is provided it gets the singleton instance of the corresponding controller
    * When a model is provided it gets a unique instance of the corresponding controller
    * Renders the named template using this controller
    * Sets the model of the corresponding controller
    

    当然你这个特点应该将 {{render}} 换为使用 {{partial}} , 只是部分 comments 的 html 片段不一样, 但是上下文中使用的 model 是一样的, 所以第二步中可以

    1. 在 template 中使用 {{partial 'comments'}} 不用传递当前 template 所对应的 controller 上下文中的 model, 他会自动拥有这个 context 可以直接使用
    2. 最好将 partial 使用的 template 使用 "_" 开头(类似 rails 中的 partial html 命名). 例如: _comments.hbs , 里面就直接 {{#each post.comments as |comment|}} 使用就好

    {{partial}} 寻找的几个特点在文档中也有写:

    * The partial helper renders another template without changing the template context
    * If a "_nav" template isn't found, the partial helper will fall back to a template named "nav".  ({{partial "nav"}})
    * The parameter supplied to partial can also be a path to a property containing a template name
    
  • Ruby VS Scala at 2015年05月05日

    scala 的编译时间让我挺难受的...

  • 现在可以关注人了 at 2015年04月22日
  • Self Hosted Gem Server at 2015年04月13日

    docker 用起来好方便~

  • Rust 发布 1.0 Beta at 2015年04月07日

    了解过后, 我头大了两圈....... 还是实用主义好

  • 好,支持,威武,有希望了!

  • 这种问题, 可以考虑 MySQL 之外的解决方案. 因为这种搜索方案会越来越复杂. 考虑使用 ElasticSearch 的全文索引方案, {key: value} 的属性匹配搜索会高效很多.

  • 新版 MacBook 完全没风扇了 at 2015年03月10日

    便携办公型呀~

  • @bluesky0318 Grape 的问题完全可以在 Grape Github 上找到答案.

    但另外, 如果是附件管理的 API 到可以看看 Kod Explorer

  • 推荐个 商城的开源项目? at 2015年02月25日

    php 的话 prestashop 也可以, 结构挺清晰, 一条主处理流程, 挂接很多 hook 插入功能. 但 hook 多了也有点烧脑...

  • 选用哪种 url 风格比较好? at 2015年02月12日

    #1楼 @cysh "url可以显示中文"

    浏览器根据编码规则解析的

  • @linjunhalida 我倒认为得看具体需要完成的任务情况了, 如果在现有的模型下出现的问题, 业务出现的问题的复杂程度是在能够接受的范围内, 我到觉得是一个可行方案. 另外对中间出现了错误查看中间状态的情况, 同样可以有好的处理方法, (理想一点哈)任何环节都可能出现问题, 那你可以在任何环节针对出现的问题对任务回滚以及异常信息集中报告处理, 让错误及早发现清空任务所有已做任务, 让任务做到等幂性质可重复执行~ 这些都是可控的, 当然也是有开发代价的.

    拥有主进程控制的方法, 让我想到类似 "microservices", 主方法不断的调用其他系统所提供的服务接口即可, 出现问题各自服务记录(可汇总到 airbrake 类似产品), 可同时返回错误信息主控制进程报告等等.

    另外, 主进程方法是否合适, 还得考虑业务的忍受程度~ 总不能让这个主进程挂个 1 小时吧? 这 1 小时带来的问题风险也不小呀?

  • Sidekiq , 不同的服务器上监听不同的任务队列, 然后信息通过 redis 队列中的任务参数传过去(尽量为字符串类型的参数).

    这样, 不同的 queue1 -> queue2 -> queue3 -> queue4 可以一次传递下去, 并且可以在任何一个 queue 的环节控制是否往下一个 queue 中发任务或者向另外一个 queue 发任务.