Isomorphic and bulletproof πͺ cookies for meteor.js
applications with support of Client, Server, Browser, Cordova, Meteor-Desktop, and other Meteor-supported environments.
- π¨βπ» Stable codebase, 320.000+ downloads;
- π¨βπ¬ ~96% Tests coverage;
- π¦ No external dependencies, no
underscore
, nojQuery
, noBlaze
; - π₯ Full support with same API across Server and Client environments;
- π± Compatible with Cordova, Browser, Meteor-Desktop, and other Meteor's Client environments;
- γοΈ Unicode support as cookies' value;
- π¨βπ»
String
,Array
,Object
, andBoolean
are supported cookies' value types; - βΏ IE support, thanks to @derwok;
- π¦ Looking for Client's (Browser) persistent storage? Try
ClientStorage
package.
meteor add ostrio:cookies
import { Cookies } from 'meteor/ostrio:cookies';
- Cordova compatible? Cordova usage β This recommendation is only for outgoing
Client -to-> Server
Cookies;Server -to-> Client
cookies work out-of-the-box. Enable withCredentials. Enable{allowQueryStringCookies: true}
and{allowedCordovaOrigins: true}
on bothClient
andServer
. When those two options are set totrue
Cookies going to be transferred to server via get-query. As security measure only whenOrigin
header matches^http://localhost:12[0-9]{3}$
expression. Meteor/Cordova connect throughlocalhost:12XXX
, local server, for outgoing requests, this also instructs the server to respond with the requested cookies (sent as GET-Parameters) in the response asSet-Cookie
header. The reason for this workaround is the general lack of cookie support in Meteor/Cordova when setting in the client β but cookies set by the server are always sent along with every request; - Cookies are missing on Server β In 99% cases it's caused by Meteor's
webapp
http server callback-chain disorder. Make surenew Cookies()
is called before Routes are registered. Routing packages usually take care of*
(e.g. catch-all or 404) route, not passing request further to callback-chain. And as freshly installed package it would be placed at the end of.meteor/packages
file, where list-order matters. We recommend to placeostrio:cookies
package above all community packages in.meteor/packages
list; - Meteor-Desktop compatibility: meteor-cookies can be used in meteor-desktop projects as well. As meteor-desktop works exactly like Cordova, all Cordova requirements and recommendations apply.
- Note β On a server, cookies will be set only after headers are sent (on next route or page reload). To send cookies from Client to Server without a page reload use
send()
method. - Server Usage Note β On a server Cookies implemented as a middleware. To get access to current user's cookies use
req.Cookies
instance. For more - see examples section below.
Create new instance of Cookies
opts.auto
{Boolean} - [Server] Auto-bind in middleware asreq.Cookies
, by defaulttrue
opts.handler
{Function} - [Server] Middleware function (e.g. hook/callback called within middleware pipeline) with single argumentcookies
asCookies
instance. See "Alternative Usage" sectionopts.onCookies
{Function} - [Server] Callback/hook triggered after.send()
method called on Client and received by Server, called with single argumentcookies
asCookies
instance. Note: this hook available only ifauto
option istrue
opts.TTL
{Number|Boolean} - Default cookies expiration time (max-age) in milliseconds, by default -false
(session, no TTL)opts.runOnServer
{Boolean} - Set tofalse
to avoid server usage (by default -true
)opts.allowQueryStringCookies
{Boolean} - Allow passing Cookies in a query string (in URL). Primary should be used only in Cordova environment. Note: this option will be used only on Cordovaopts.allowedCordovaOrigins
{Regex|Boolean} - [Server] Allow setting Cookies from that specific origin which in Meteor/Cordova is localhost:12XXX. Set to default^http:\/\/localhost:12[0-9]{3}$
if set totrue
. Default:false
import { Cookies } from 'meteor/ostrio:cookies';
const cookies = new Cookies();
Read a cookie. If the cookie doesn't exist a null
will be returned.
key
{String} - The name of the cookie to read
Create/overwrite a cookie.
key
{String} - The name of the cookie to create/overwritevalue
{String|Number|Boolean|Object|Array} - The value of the cookieopts
{Object} - [Optional]opts.expires
{Number|Date|Infinity} - [Optional] Date, Number as milliseconds or Infinity for a never-expires cookie. If not specified the cookie will expire at the end of session (number as milliseconds or Date object)opts.maxAge
{Number} - [Optional] The max-age in seconds (e.g.31536e3
for a year)opts.path
{String} - [Optional] The path from where the cookie will be readable. E.g., "/", "/mydir"; if not specified, defaults to the current path of the current document location (string or null). The path must be absolute (see RFC 2965). For more information on how to use relative paths in this argument, see: docsopts.domain
{String} - [Optional] The domain from where the cookie will be readable. E.g., "example.com", ".example.com" (includes all subdomains) or "subdomain.example.com"; if not specified, defaults to the host portion of the current document location (string or null)opts.secure
{Boolean} - [Optional] The cookie will be transmitted only over secure protocol ashttps
opts.httpOnly
{Boolean} - [Optional] An HttpOnly cookie cannot be accessed by client-side APIs, such as JavaScript. This restriction eliminates the threat of cookie theft via cross-site scripting (XSS)opts.sameSite
{Boolean} {String: None, Strict, or Lax} - [Optional] Cross-site cookies usage policy. Read more on wikipedia, web.dev, and ietf. Default:false
opts.firstPartyOnly
{Boolean} - [Optional] Deprecated usesameSite
instead
remove()
- Remove all cookies on current domainremove(key)
- Remove a cookie on current domainremove(key, path, domain)
:key
{String} - The name of the cookie to create/overwritepath
{String} - [Optional] The path from where the cookie was readable. E.g., "/", "/mydir"; if not specified, defaults to the current path of the current document location (string or null). The path must be absolute (see RFC 2965). For more information on how to use relative paths in this argument, read moredomain
{String} - [Optional] The domain from where the cookie was readable. E.g., "example.com", ".example.com" (includes all subdomains) or "subdomain.example.com"; if not specified, defaults to the host portion of the current document location (string or null)
Check whether a cookie exists in the current position, returns boolean value
key
{String} - The name of the cookie to check
Returns an array of all readable cookies from this location
Send all current cookies to server.
/* Both Client & Server */
import { Meteor } from 'meteor/meteor';
import { Cookies } from 'meteor/ostrio:cookies';
const cookies = new Cookies();
/* Client */
if (Meteor.isClient) {
cookies.set('locale', 'en'); //true
cookies.set('country', 'usa'); //true
cookies.set('gender', 'male'); //true
cookies.get('gender'); //male
cookies.has('locale'); //true
cookies.has('city'); //false
cookies.keys(); //['locale', 'country', 'gender']
cookies.remove('locale'); //true
cookies.get('locale'); //undefined
cookies.keys(); //['country', 'gender']
cookies.remove(); //true
cookies.keys(); //[""]
cookies.remove(); //false
}
/* Server */
if (Meteor.isServer) {
const { WebApp } = require('meteor/webapp');
WebApp.connectHandlers.use((req, res, next) => {
cookies = req.Cookies;
cookies.set('locale', 'en'); //true
cookies.set('country', 'usa'); //true
cookies.set('gender', 'male'); //true
cookies.get('gender'); //male
cookies.has('locale'); //true
cookies.has('city'); //false
cookies.keys(); //['locale', 'country', 'gender']
cookies.remove('locale'); //true
cookies.get('locale'); //undefined
cookies.keys(); //['country', 'gender']
cookies.remove(); //true
cookies.keys(); //[""]
cookies.remove(); //false
next(); // Pass request to the next handler
});
}
/* Both Client & Server */
import { Meteor } from 'meteor/meteor';
import { Cookies } from 'meteor/ostrio:cookies';
/* Client */
if (Meteor.isClient) {
const cookies = new Cookies();
cookies.set('gender', 'male'); //true
cookies.get('gender'); //male
cookies.has('city'); //false
cookies.keys(); //['gender']
}
/* Server */
if (Meteor.isServer) {
const { WebApp } = require('meteor/webapp');
const cookie = new Cookies({
auto: false, // Do not bind as a middleware by default (recommended, but not required)
handler(cookies) {
cookies.set('gender', 'male'); //true
cookies.get('gender'); //male
cookies.has('city'); //false
cookies.keys(); //['gender']
}
});
WebApp.connectHandlers.use(cookie.middleware());
}
- Clone this package
- In Terminal (Console) go to directory where package is cloned
- Then run:
# Default
meteor test-packages ./
# With custom port
meteor test-packages ./ --port 8888
- Upload and share files using βοΈ meteor-files.com β Continue interrupted file uploads without losing any progress. There is nothing that will stop Meteor from delivering your file to the desired destination
- Use β² ostr.io for Server Monitoring, Web Analytics, WebSec, Web-CRON and SEO Pre-rendering of a website
- Star on GitHub
- Star on Atmosphere
- Sponsor via GitHub
- Support via PayPal