最近完成了一个页面, 用来做书签搜集, 界面是这样的:
实际上架构分成了 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-Credentials
为 true
时, 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.json
的 permissions
配置好直接生效了
Chrome 扩展里可以配置运行一些 url 可以被插件访问, 不考虑安全性, 我用了 http://*/
不过如果不生效, chrome.cookies.get
方法也是能获取 Cookie 的
以上就是我在 Topics 项目遇到的关于 Cookie 的问题
返回博客主页: http://blog.tiye.me
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。