Isomorphic Cookies
Isomorphic and bulletproof 🍪 cookies for meteor.js applications with support of Client, Server, Browser, Cordova, and other Meteor-supported environments.
- 👨💻 Stable codebase, 80.000+ downloads;
- 👨🔬 ~96% Tests coverage;
- 📦 No external dependencies, no
underscore, nojQuery, noBlaze; - 🖥 Full support with same API on both Server and Client environments;
- 📱 Compatible with Cordova, Browser and other Meteor's Client environments;
- ㊗️ Unicode support as cookies' value;
- 👨💻
String,Array,Object, andBooleanare supported cookies' value types; - ♿ 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:
- Cordova compatible? Cordova usage — This recommendation is only for outgoing
Client -to-> ServerCookies;Server -to-> Clientcookies work out-of-the-box. Enable withCredentials. Enable{allowQueryStringCookies: true}and{allowedCordovaOrigins: true}on bothClientandServer. When those two options are set totrueCookies going to be transfered to server via get-query. As security measure only whenOriginheader 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-Cookieheader. 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
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 "Alternative 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|Boolean} - Default cookies expiration time (max-age) in milliseconds, by default -false(session, no TTL)opts.runOnServer{Boolean} - Set tofalseto 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
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} {String: None, Strict, or Lax} - [Optional] Cross-site cookies usage policy. Read more on wikipedia, web.dev, and ietf. Default:falseopts.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}
Alternative 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
Support our open source contributions
- Sponsor via GitHub
- Support via PayPal
- Use ostr.io — Monitoring, Analytics, WebSec, Web-CRON and Pre-rendering for a website