简体   繁体   中英

How can I get a browser cookie from the server in Meteor for session handling?

I am currently re-writing a PHP+Mongodb application in Meteor.

In the application, a session cookie that contains only a unique identifier is used. The server gets the browser's cookie and uses its value to load data from a collection. This is useful for knowing the client's current state. Using Meteor I need to be able to get the value of the browser cookie from the server code. How can I accomplish this?

In PHP, one might do it like so:

if(isset($_COOKIE["cookie_name"])) {
    //there is a browser cookie set with a name "cookie_name", 
    //and now I can act on that cookie's value, straight from the server
    echo $_COOKIE["cookie_name"];
}

I'm not sure if meteor's Session is what I'm looking for mostly because:

  • It doesn't seem to persist between page reloads (it creates a fresh session each reload)

  • There must be a way to disconnect the session by simply deleting the browser cookie

I'd like to handle this on the server because I want my sessions data to be private. Data about a session that isn't presented through a view (except for the session's unique identifier) must never be sent to the client.

If I'm understanding correctly, you don't actually care about the cookie, you care about having user-specific data.

Comparison to PHP

Meteor clients communicate with the server via DDP which is an abstraction on top of http. Things like 'cookies' don't exist in the DDP level. Rather, you have access to powerful constructs like sync'd database collections and built-in remote procedure calls.

Meteor's Session object is a client-only concept that is designed for reactivity. It is not persisted between client visits and the server does not have access to it.

The rough equivalent to PHP's SESSION is a Meteor Collection, which is actually more durable than PHP's SESSION because it is persisted to the database.

User-specific data

Tracking user-specific data like you want in Meteor can be broken down into two parts:

  1. authenticated users
  2. anonymous users

Re: #1 - authenticated users

As @Tarang and @Cuberto have pointed out, the Meteor Accounts system (ex. accounts-password) has the concept of user-specific data built-in. It creates and manages the Meteor.users collection for you and provides the Meteor.user() function for getting an object specific to that user. It even has a built-in method for user-modifiable data in the profile field of the user object. The profile field is automatically published and is reactive as well (since Meteor.user() is reactive).

function doSomething () {
  var currentUser = Meteor.user(),
      profile;

  if (!currentUser) {
    // handle 'not authenticated' case
  } else {
    // already logged in
    profile = currentUser.profile || {name:'<not set>'};
    console.log('user ', profile.name, ' wants to doSomething');
  }
}

You can build your own authentication method but that seems like a recipe for disaster. Easier to write a script that converts from your existing DB structure to the Meteor Accounts structure and do it once in a big dump when you are ready to migrate your users over.

So the Meteor convention is:

  • User-specific data that the user should be able to modify goes in the user.profile field. Ex. user.profile.firstname , user.profile.lastname
  • User-specific data that is restricted should go on the root user object.
    Ex. The meteor-roles package stores user roles in a restricted, user.roles field.

Here are the relevant docs: http://docs.meteor.com/#meteor_user

Re: #2 - anonymous users

Meteor Accounts does not track anonymous users so you will need to track them yourself. You can use various methods to do this but the core is to store some identifying token on the client's machine in client code (either into localStorage or a cookie).

If you don't need to store user-specific data on the server and only want to change client-side stuff, such as what the users see, then you can do everything from the client.

If you need to store data on the server for anonymous users then you'll have to send the identifying token to the server along with each Meteor method call or database interaction (essentially what PHP does with the SESSION cookie). On the server, create a Collection called 'anonymousData' which will contain all of the user-specific info for your anonymous users, keyed by id token. The server-side functions can query that Collection with the id token the client passes to retrieve user-specific info for that user.

Keep in mind that if the user clears their cookies or deletes localStorage that data will be orphaned so some kind of a last-used check is important.

You would have to parse the headers out. Look for a package called ip on atmosphere. This is trickier than it sounds though.

One thing you could do is instead of using cookie's use localStorage.

Try localStorage

localStorage.setItem("name", "value");

and to get a value:

localStorage.getItem("name");

Meteor already uses localStorage to store the user's logged in state & ID

The cookie information is contained in the headers section of the response object of a HTTP call done with Meteor.http.call() called from the client using Meteor.call() . set-cookie is an array containing any cookies sent over from the server. Here's a screenshot of one of the results:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM