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.
You can take a look at the user management example here:
How to login the user:
https://github.com/strongloop/loopback-example-user-management/blob/master/server/boot/routes.js#L20-L41
Set to use loopback token in server:
https://github.com/strongloop/loopback-example-user-management/blob/337d892643f79513f2bed0b4a042aa204019fd79/server/server.js#L15
If I'm understanding this correctly:
Step 1:
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:
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 :)
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? 馃槥
Most helpful comment
With LB3, I need token in cookie, a way for doing it
In
server/middleware.jsonYou alse need to install
cookie-parserin your dependenciesIn
server/config.jsonaddIn production you shoud have a different secret
server/config.production.jsonIn
common/models/user-account.js(based on User model)Be sure to have
withCredentialsenable during AJAX call if you have cross domain environment CORS