1

最近完成了一个页面, 用来做书签搜集, 界面是这样的:
实际上架构分成了 3 个部分, 通过 Cookie 把三个关联起来,

  • API 服务器

http://topics-api.tiye.me
https://github.com/tiye/topics-server
服务器用的是 Express + Mongoose, 数据库操作不大熟悉, 当作练习,
实现基本的 CURD 功能, 以及对 Cookie 中的 token 进行验证

  • Chrome Extension

https://github.com/tiye/topics-crx
往服务器 POST 书签, 使用网页端登录好的 Cookie

  • 网页界面

http://topics.tiye.me/
https://github.com/tiye/topics.tiye.me
借助 Vue 实现的界面, 书签是个列表, 所以做的是列表管理
这里会像服务器进行跨域连接...

跨域

这样的架构会有一些问题, 主要就是跨域共享 Cookie 的问题:

  • 服务端支持跨域

一般简单的跨域, 基于 Express 的话, 直接用 cors 模块生成的跨域 Headers 就好了
https://github.com/troygoode/node-cors

express = require 'express'
cors = require 'cors'
app = express()

app.use cors()

不过这里会遇到问题, cors 给的例子里 origin 是在定义路由时定死的.
我个人的书签, 对安全性要求不高, 更多是未开发方便, 于是这里不够灵活.

另外, Access-Control-Allow-Credentialstrue 时, origin 不能用 *
为了同时满足多个 origin 和带 Cookie, 就要自己处理请求头
这个花了我好久.. 但是因为看过公司里这个需求的代码, 最后方案是这样

每个请求都走一遍中间件, 取出 headers 里的域名, 写到 CORS 头部去:

app = express()

app.all '*', (req, res, next) ->
  if req.headers.origin?
    res.header("Access-Control-Allow-Origin", req.headers.origin)
    res.header("Access-Control-Allow-Credentials", true)
    res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS')
    # 下面一行意义不明确...
    res.header("Access-Control-Allow-Headers", "X-Requested-With, AUTHORIZATION")
  next()

而客户端每个发起的跨域请求就需要配置, 让代码主动加上 Cookie:

$.ajax
  url: "#{apiHost}#{url}"
  type: type
  data: data
  xhrFields:
    withCredentials: true
  • OPTIONS 请求带 Cookie

另外有个问题是, OPTIONS 请求是浏览器在跨域请求时自动发出的.
在 Chrome Canary 测试时, 我观察到了 Cookie, 以为正常了..
后来在 dev 版(34)发现出了问题, OPTIONS 请求没有带上 Cookie
因为我的数据请求是要验证的, 发送 OPTIONS 没有带信息的话, 就回抱错

找了个比较粗糙的办法, 所有 OPTIONS 请求直接返回数据,
这样, 中间件写在 headers 当中的 CORS 信息就返回到客户端了:

app.options '*', (req, res) ->
  res.json status: yes
  • 调试过程 Cookie domain

另外有个问题是 Cookie 的 domain, 本来应该没问题的,
但是本地调试发现, 本地修改 hosts 模拟线上环境后, 估计是 DNS 缓存, 不能马上切回来..
无奈本地配置了 topics-api.tiye.dev 来模拟, 因此要考虑 Cookie domain

这里是加了代码, 通过 req.headers.origin 来生成 Cookie 的 domain

  • Chrome 扩展发送请求带上 Cookie

这个比较简单, 在 manifest.jsonpermissions 配置好直接生效了
Chrome 扩展里可以配置运行一些 url 可以被插件访问, 不考虑安全性, 我用了 http://*/
不过如果不生效, chrome.cookies.get 方法也是能获取 Cookie 的

以上就是我在 Topics 项目遇到的关于 Cookie 的问题


返回博客主页: http://blog.tiye.me


题叶
17.3k 声望2.6k 粉丝

Calcit 语言作者


引用和评论

0 条评论