Open artofspeed opened 5 years ago
I'm having the same problem, is there any information of how to fully destroy a session and do not return something like koa:sess= ; koa:sess.sig=123213123
?
tl;dr currently the destroy
method in lib/context.js
only sets the cookie data to be blank, instead of expiring it. This is because koa
uses the cookies
module, but doesn't take advantage of the additional options, or the available API on the cookie itself.
Long story:
The code only destroys the data contained in the cookie, not the cookie itself, that is referenced with opts.key
:
Once the session is destroyed by the key name, the session named by opts.key
is destroyed. This session is called koa:sess
by default, or can be the passed cookie name.
https://github.com/koajs/session/blob/10bb12246699101a0c87a2f3e2e09b1a79e10e33/index.js#L60-L75
The .sig
cookie exists because by default, the options declare the cookie should be signed, which is part of the cookies
library that koa uses.
module: cookies/index.js
Cookies.prototype.get = function(name, opts) {
var sigName = name + ".sig"
, header, match, value, remote, data, index
, signed = opts && opts.signed !== undefined ? opts.signed : !!this.keys
header = this.request.headers["cookie"]
if (!header) return
match = header.match(getPattern(name))
if (!match) return
value = match[1]
if (!opts || !signed) return value
remote = this.get(sigName)
if (!remote) return
data = name + "=" + value
if (!this.keys) throw new Error('.keys required for signed cookies');
index = this.keys.index(data, remote)
if (index < 0) {
this.set(sigName, null, {path: "/", signed: false })
} else {
index && this.set(sigName, this.keys.sign(data), { signed: false })
return value
}
};
Cookies.prototype.set = function(name, value, opts) {
var res = this.response
, req = this.request
, headers = res.getHeader("Set-Cookie") || []
, secure = this.secure !== undefined ? !!this.secure : req.protocol === 'https' || req.connection.encrypted
, cookie = new Cookie(name, value, opts)
, signed = opts && opts.signed !== undefined ? opts.signed : !!this.keys
if (typeof headers == "string") headers = [headers]
if (!secure && opts && opts.secure) {
throw new Error('Cannot send secure cookie over unencrypted connection')
}
cookie.secure = secure
if (opts && "secure" in opts) cookie.secure = opts.secure
if (opts && "secureProxy" in opts) {
deprecate('"secureProxy" option; use "secure" option, provide "secure" to constructor if needed')
cookie.secure = opts.secureProxy
}
pushCookie(headers, cookie)
if (opts && signed) {
if (!this.keys) throw new Error('.keys required for signed cookies');
cookie.value = this.keys.sign(cookie.toString())
cookie.name += ".sig"
pushCookie(headers, cookie)
}
var setHeader = res.set ? http.OutgoingMessage.prototype.setHeader : res.setHeader
setHeader.call(res, 'Set-Cookie', headers)
return this
};
I'll create a pull request to fix this behaviour.
Say cookie name is
foo
. When you doctx.session = null;
, on client side, the cookiefoo.sig
is cleared, the cookiefoo
is still there with its original value.Why is it done this way? How to do a full clean?