Isomorphic Cookies
Isomorphic and bulletproof 🍪 cookies for meteor.js applications with support of Client, Server, Browser, Cordova, and other Meteor-supported environments.
- 👷 100% Tests coverage;
- 📦 No external dependencies, no
underscore, nojQuery, noBlaze; - 🖥 Full support with same API on both Server and Client environments;
- 📱 Support for Cordova, Browser and other Meteor's Client environments;
- ㊗️ With Unicode support for cookies' value;
- 👨💻 With
String,Array,Object, andBooleansupport as cookies' value; - ♿ IE support, thanks to @derwok;
- 📦 Looking for Client's (Browser) persistent storage? Try
ClientStoragepackage.
Install:
meteor add ostrio:cookies
ES6 Import:
1import { Cookies } from 'meteor/ostrio:cookies';
FAQ:
- Cookies are missing on Server — In 99% cases it's caused by Meteor's
webapphttp 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/packagesfile, where list-order matters. We recommend to placeostrio:cookiespackage above all community packages in.meteor/packageslist.
API:
- 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.Cookiesinstance. For more - see examples section below.
Fetch cookies new Cookies(opts) [Isomorphic]
Create new instance of Cookies
opts.auto{Boolean} - [Server] Auto-bind in middleware asreq.Cookies, by defaulttrueopts.handler{Function} - [Server] Middleware function (e.g. hook/callback called within middleware pipeline) with single argumentcookiesasCookiesinstance. See "Alternate Usage" sectionopts.onCookies{Function} - [Server] Callback/hook triggered after.send()method called on Client and received by Server, called with single argumentcookiesasCookiesinstance. Note: this hook available only ifautooption istrueopts.TTL{Number} - Default cookies expiration time (max-age) in milliseconds, by default -session(no TTL)opts.runOnServer{Boolean} - Set tofalseto avoid server usage (by default -true)
1import { Cookies } from 'meteor/ostrio:cookies'; 2const cookies = new Cookies();
cookies.get(key) [Isomorphic]
Read a cookie. If the cookie doesn't exist a null will be returned.
key{String} - The name of the cookie to read
cookies.set(key, value, [opts]) [Isomorphic]
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.31536e3for 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 ashttpsopts.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} - [Optional] Cookie which can only be sent in requests originating from the same origin as the target domain. Read more on wikipedia and ietfopts.firstPartyOnly{Boolean} - [Optional] Deprecated usesameSiteinstead
cookies.remove([key], [path], [domain]) [Isomorphic]
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)
cookies.has(key) [Isomorphic]
Check whether a cookie exists in the current position, returns boolean value
key{String} - The name of the cookie to check
cookies.keys() [Isomorphic]
Returns an array of all readable cookies from this location
cookies.send([callback]) [Client]
Send all current cookies to server
Examples:
1/* Both Client & Server */ 2import { Meteor } from 'meteor/meteor'; 3import { Cookies } from 'meteor/ostrio:cookies'; 4const cookies = new Cookies(); 5 6/* Client */ 7if (Meteor.isClient) { 8 cookies.set('locale', 'en'); //true 9 cookies.set('country', 'usa'); //true 10 cookies.set('gender', 'male'); //true 11 12 cookies.get('gender'); //male 13 14 cookies.has('locale'); //true 15 cookies.has('city'); //false 16 17 cookies.keys(); //['locale', 'country', 'gender'] 18 19 cookies.remove('locale'); //true 20 cookies.get('locale'); //undefined 21 22 cookies.keys(); //['country', 'gender'] 23 24 cookies.remove(); //true 25 cookies.keys(); //[""] 26 27 cookies.remove(); //false 28} 29 30/* Server */ 31if (Meteor.isServer) { 32 const { WebApp } = require('meteor/webapp'); 33 34 WebApp.connectHandlers.use((req, res, next) => { 35 cookies = req.Cookies; 36 37 cookies.set('locale', 'en'); //true 38 cookies.set('country', 'usa'); //true 39 cookies.set('gender', 'male'); //true 40 41 cookies.get('gender'); //male 42 43 cookies.has('locale'); //true 44 cookies.has('city'); //false 45 46 cookies.keys(); //['locale', 'country', 'gender'] 47 48 cookies.remove('locale'); //true 49 cookies.get('locale'); //undefined 50 51 cookies.keys(); //['country', 'gender'] 52 53 cookies.remove(); //true 54 cookies.keys(); //[""] 55 56 cookies.remove(); //false 57 58 next(); // Pass request to the next handler 59 }); 60}
Alternate Usage
1/* Both Client & Server */ 2import { Meteor } from 'meteor/meteor'; 3import { Cookies } from 'meteor/ostrio:cookies'; 4 5/* Client */ 6if (Meteor.isClient) { 7 const cookies = new Cookies(); 8 cookies.set('gender', 'male'); //true 9 cookies.get('gender'); //male 10 cookies.has('city'); //false 11 cookies.keys(); //['gender'] 12} 13 14/* Server */ 15if (Meteor.isServer) { 16 const { WebApp } = require('meteor/webapp'); 17 18 const cookie = new Cookies({ 19 auto: false, // Do not bind as a middleware by default (recommended, but not required) 20 handler(cookies) { 21 cookies.set('gender', 'male'); //true 22 cookies.get('gender'); //male 23 cookies.has('city'); //false 24 cookies.keys(); //['gender'] 25 } 26 }); 27 28 WebApp.connectHandlers.use(cookie.middleware()); 29}
Running Tests
- Clone this package
- In Terminal (Console) go to directory where package is cloned
- Then run:
Meteor/Tinytest
# Default meteor test-packages ./ # With custom port meteor test-packages ./ --port 8888 # With local MongoDB and custom port MONGO_URL="mongodb://127.0.0.1:27017/cookies-tests" meteor test-packages ./ --port 8888
Support this project:
- Become a patron — support my open source contributions with monthly donation
- Use ostr.io — Monitoring, Analytics, WebSec, Web-CRON and Pre-rendering for a website