Loopback: Setting access token cookie?

Created on 13 Mar 2016  路  13Comments  路  Source: strongloop/loopback

I want to use a cookie to keep a user logged in.

On this page here they say

To use cookies for authentication, add the following to server.js
(before boot):

app.use(loopback.token({ model: app.models.accessToken }));

Seemed simple enough. I figured the cookies were set by Loopback automatically during the login process but it's still not working, I check my cookies in Chrome dev tools and none are set.

Am I missing something? Otherwise, what's the best way to hook into the login method to have set the cookie/header?

I found docs on the loopback.token() method here, which says exactly where it checks for the token.

triaging

Most helpful comment

With LB3, I need token in cookie, a way for doing it

In server/middleware.json

 "session:before": {
   "cookie-parser": {
     "params": "${cookieSecret}"
   }
 },
 "session": {},
 "auth": {
   "loopback#token": {}
 },

You alse need to install cookie-parser in your dependencies
In server/config.json add

"cookieSecret": "__TOREPLACEWITHPROPERRANDOMSECRET__",

In production you shoud have a different secret server/config.production.json

In common/models/user-account.js (based on User model)

  UserAccount.afterRemote('login', function(ctx){
    ctx.res.cookie('access_token', ctx.result.id, { signed: true, maxAge: ctx.result.ttl * 1000 });
    return Promise.resolve();
  });

  UserAccount.afterRemote('logout', function(ctx){
    ctx.res.clearCookie('access_token');
    return Promise.resolve();
  });

Be sure to have withCredentials enable during AJAX call if you have cross domain environment CORS

All 13 comments

If I'm understanding this correctly:

Step 1:

https://github.com/strongloop/loopback-example-user-management/blob/337d892643f79513f2bed0b4a042aa204019fd79/server/server.js#L15

sets the server up to check for an access token cookie or header or query string param.

Step 2:

https://github.com/strongloop/loopback-example-user-management/blob/master/server/boot/routes.js#L20-L41

Checks the email+password and generates an access token.

But I've followed this example and the cookie never gets set. I don't see it in Chrome dev tools. Is User.login() supposed to set a cookie? Or are you supposed to do that manually?

If so, how exactly are you supposed to set the cookie?
This documentation:
http://apidocs.strongloop.com/loopback/#loopback-token
leads me to believe I'm supposed to set a cookie named "authorization" with the access token. Is that wrong?

Because I've tried that and it didn't work. If I navigate to a protected route I get 401, Authorization Required. Double checked the cookie was set, copy-pasted it on the end of the url like so:
?access_token=<accessToken>
And it works, I get access.

It's just not using the cookie.

EUREKA. I got it to work. The cookie wasn't being signed.

Sorry, I'm pretty much new to Express and lower-level stuff like this. I remembered reading that the cookie had to be signed but it slipped my mind that I had to pass "signed: true".

@kenmorechalfant Glad you got it working. ;) Closing.

@kenmorechalfant Could you dump the snippet of how exactly you signed the cookie and where did you passed "signed:true"? I'm facing exactly the same problem. Thanks

@mkumr Yes, I haven't touched this code in months but here it is, hope it helps:

routes.js

module.exports = function(app) {
  app.post('/login', function(req, res) {

    app.models.User.login({
      email: req.body.email,
      password: req.body.password
    }, 'user', function(err, token) {
      if (err) {
        res.send('<a href="/">YA FAILED</a>');
        return;
      }

      res.cookie('access_token', token.id, { signed: true , maxAge: 300000 });
      // res.set('X-Access-Token', token.id);
      res.render('token', {
        email: req.body.email,
        accessToken: token.id
      });
    });
  });

  app.get('/token', function(req, res) {
      res.render('token');
  });
};

Do you need to set up cookieParser middleware? I did

"session:before": {
"loopback#cookieParser": {
"params": "${cookieSecret}"
}
},
"session": {
"loopback#session": {
"params": {
"secret": "kitty",
"saveUninitialized": true,
"resave": true }
}
},

in middleware.json but node complained

${cookieSecret} does not resolve to a valid value. "cookieSecret" must be resolvable by app.get().,

Anyone know how to resolve the cookieSecret?

Find the solution, I need to set an express field like app.set('cookieSecret', 'kitty'); cookie-parser and session packages are required too.

@lazydino , what do you mean by "cookie-parser and session packages are required too"?
Just include a "var cookieparser = require("cookieparser") at the beginning of server.js" ?

@fabianorodrigo cookie-parser is middleware. You must .use() it for it to do anything. Look at the example on the cookie-parser github page: https://github.com/expressjs/cookie-parser

@kenmorechalfant thanks so much bro. i love you so much, this has been really helpful :)

With LB3, I need token in cookie, a way for doing it

In server/middleware.json

 "session:before": {
   "cookie-parser": {
     "params": "${cookieSecret}"
   }
 },
 "session": {},
 "auth": {
   "loopback#token": {}
 },

You alse need to install cookie-parser in your dependencies
In server/config.json add

"cookieSecret": "__TOREPLACEWITHPROPERRANDOMSECRET__",

In production you shoud have a different secret server/config.production.json

In common/models/user-account.js (based on User model)

  UserAccount.afterRemote('login', function(ctx){
    ctx.res.cookie('access_token', ctx.result.id, { signed: true, maxAge: ctx.result.ttl * 1000 });
    return Promise.resolve();
  });

  UserAccount.afterRemote('logout', function(ctx){
    ctx.res.clearCookie('access_token');
    return Promise.resolve();
  });

Be sure to have withCredentials enable during AJAX call if you have cross domain environment CORS

@superkhau Don't you think the above comment added to the docs? 馃槥

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ian-lewis-cs picture ian-lewis-cs  路  4Comments

bajtos picture bajtos  路  4Comments

bajtos picture bajtos  路  3Comments

ImanMh picture ImanMh  路  4Comments

bryannaegele picture bryannaegele  路  4Comments