Skip to content

feature(login) keep session living #444

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: canary
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/index.js
Original file line number Diff line number Diff line change
@@ -240,7 +240,7 @@ var AngularFullstackGenerator = yeoman.generators.Base.extend({
});

var angModules = [
"'ngCookies'",
"'ngStorage'",
"'ngResource'",
"'ngSanitize'"
];
2 changes: 1 addition & 1 deletion app/templates/_bower.json
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
"bootstrap-sass-official": "~3.1.1",<% } %>
"bootstrap": "~3.1.1",<% } %>
"angular-resource": ">=1.2.*",
"angular-cookies": ">=1.2.*",
"ngstorage": "~0.3.0",
"angular-sanitize": ">=1.2.*",<% if(filters.ngroute) { %>
"angular-route": ">=1.2.*",<% } %><% if(filters.uibootstrap) { %>
"angular-bootstrap": "~0.11.0",<% } %>
15 changes: 15 additions & 0 deletions app/templates/client/app/account(auth)/account(coffee).coffee
Original file line number Diff line number Diff line change
@@ -7,6 +7,13 @@ angular.module '<%= scriptAppName %>'
templateUrl: 'app/account/login/login.html'
controller: 'LoginCtrl'

.when '/login/:sessionToken',
template: ' '
controller: ($routeParams, Auth, $location) ->
if $routeParams.sessionToken
Auth.setSessionToken $routeParams.sessionToken, ->
$location.path "/"
return
.when '/signup',
templateUrl: 'app/account/signup/signup.html'
controller: 'SignupCtrl'
@@ -22,6 +29,14 @@ angular.module '<%= scriptAppName %>'
templateUrl: 'app/account/login/login.html'
controller: 'LoginCtrl'

.state 'loginWithToken',
url: '/login/:sessionToken'
template: ' '
controller: ($stateParams, Auth, $location) ->
if $stateParams.sessionToken
Auth.setSessionToken $stateParams.sessionToken, ->
$location.path "/"
return
.state 'signup',
url: '/signup'
templateUrl: 'app/account/signup/signup.html'
17 changes: 17 additions & 0 deletions app/templates/client/app/account(auth)/account(js).js
Original file line number Diff line number Diff line change
@@ -7,6 +7,14 @@ angular.module('<%= scriptAppName %>')
templateUrl: 'app/account/login/login.html',
controller: 'LoginCtrl'
})
.when('/login/:sessionToken', {
template: ' ',
controller: function($routeParams, Auth, $location){
if ($routeParams.sessionToken) {
Auth.setSessionToken($routeParams.sessionToken, function(){$location.path('/');});
}
}
})
.when('/signup', {
templateUrl: 'app/account/signup/signup.html',
controller: 'SignupCtrl'
@@ -23,6 +31,15 @@ angular.module('<%= scriptAppName %>')
templateUrl: 'app/account/login/login.html',
controller: 'LoginCtrl'
})
.state('loginWithToken', {
url: '/login/:sessionToken',
template: ' ',
controller: function($stateParams, Auth, $location){
if ($stateParams.sessionToken) {
Auth.setSessionToken($stateParams.sessionToken, function(){$location.path('/');});
}
}
})
.state('signup', {
url: '/signup',
templateUrl: 'app/account/signup/signup.html',
Original file line number Diff line number Diff line change
@@ -9,4 +9,4 @@ angular.module '<%= scriptAppName %>'

$scope.delete = (user) ->
User.remove id: user._id
_.remove $scope.users, user
_.remove $scope.users, user
4 changes: 2 additions & 2 deletions app/templates/client/app/app(coffee).coffee
Original file line number Diff line number Diff line change
@@ -15,11 +15,11 @@ angular.module '<%= scriptAppName %>', [<%= angularModules %>]
$locationProvider.html5Mode true<% if(filters.auth) { %>
$httpProvider.interceptors.push 'authInterceptor'<% } %>
<% } %><% if(filters.auth) { %>
.factory 'authInterceptor', ($rootScope, $q, $cookieStore, $location) ->
.factory 'authInterceptor', ($rootScope, $q, $localStorage, $location) ->
# Add authorization token to headers
request: (config) ->
config.headers = config.headers or {}
config.headers.Authorization = 'Bearer ' + $cookieStore.get 'token' if $cookieStore.get 'token'
config.headers.Authorization = 'Bearer ' + $localStorage.token if $localStorage.token
config

# Intercept 401s and redirect you to login
8 changes: 4 additions & 4 deletions app/templates/client/app/app(js).js
Original file line number Diff line number Diff line change
@@ -17,13 +17,13 @@ angular.module('<%= scriptAppName %>', [<%= angularModules %>])
$httpProvider.interceptors.push('authInterceptor');<% } %>
})<% } %><% if(filters.auth) { %>

.factory('authInterceptor', function ($rootScope, $q, $cookieStore, $location) {
.factory('authInterceptor', function ($rootScope, $q, $localStorage, $location) {
return {
// Add authorization token to headers
request: function (config) {
config.headers = config.headers || {};
if ($cookieStore.get('token')) {
config.headers.Authorization = 'Bearer ' + $cookieStore.get('token');
if ($localStorage.token) {
config.headers.Authorization = 'Bearer ' + $localStorage.token;
}
return config;
},
@@ -33,7 +33,7 @@ angular.module('<%= scriptAppName %>', [<%= angularModules %>])
if(response.status === 401) {
$location.path('/login');
// remove any stale tokens
$cookieStore.remove('token');
delete $localStorage.token;
return $q.reject(response);
}
else {
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use strict'

angular.module '<%= scriptAppName %>'
.factory 'Auth', ($location, $rootScope, $http, User, $cookieStore, $q) ->
currentUser = if $cookieStore.get 'token' then User.get() else {}
.factory 'Auth', ($location, $rootScope, $http, User, $localStorage, $q) ->
currentUser = if $localStorage.token then User.get() else {}

###
Authenticate user and save token
@@ -18,7 +18,7 @@ angular.module '<%= scriptAppName %>'
password: user.password

.success (data) ->
$cookieStore.put 'token', data.token
$localStorage.token = data.token
currentUser = User.get()
deferred.resolve data
callback?()
@@ -37,7 +37,7 @@ angular.module '<%= scriptAppName %>'
@param {Function}
###
logout: ->
$cookieStore.remove 'token'
delete $localStorage.token
currentUser = {}
return

@@ -52,7 +52,7 @@ angular.module '<%= scriptAppName %>'
createUser: (user, callback) ->
User.save user,
(data) ->
$cookieStore.put 'token', data.token
$localStorage.token = data.token
currentUser = User.get()
callback? user

@@ -133,4 +133,17 @@ angular.module '<%= scriptAppName %>'
Get auth token
###
getToken: ->
$cookieStore.get 'token'
$localStorage.token


###
Set session token
@param {String} session token
@return {Promise}
###

setSessionToken: (sessionToken, callback) ->
cb = callback || angular.noop;
$localStorage.token = sessionToken
currentUser = User.get(cb)
return
31 changes: 21 additions & 10 deletions app/templates/client/components/auth(auth)/auth.service(js).js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
'use strict';

angular.module('<%= scriptAppName %>')
.factory('Auth', function Auth($location, $rootScope, $http, User, $cookieStore, $q) {
var currentUser = {};
if($cookieStore.get('token')) {
currentUser = User.get();
}
.factory('Auth', function Auth($location, $rootScope, $http, User, $localStorage, $q) {

var currentUser = $localStorage.token ? User.get() : {};

return {

@@ -22,10 +20,11 @@ angular.module('<%= scriptAppName %>')

$http.post('/auth/local', {
email: user.email,
password: user.password
password: user.password,
rememberme : user.rememberme
}).
success(function(data) {
$cookieStore.put('token', data.token);
$localStorage.token = data.token;
currentUser = User.get();
deferred.resolve(data);
return cb();
@@ -45,7 +44,7 @@ angular.module('<%= scriptAppName %>')
* @param {Function}
*/
logout: function() {
$cookieStore.remove('token');
delete $localStorage.token;
currentUser = {};
},

@@ -61,7 +60,7 @@ angular.module('<%= scriptAppName %>')

return User.save(user,
function(data) {
$cookieStore.put('token', data.token);
$localStorage.token = data.token;
currentUser = User.get();
return cb(user);
},
@@ -140,7 +139,19 @@ angular.module('<%= scriptAppName %>')
* Get auth token
*/
getToken: function() {
return $cookieStore.get('token');
return $localStorage.token;
},

/**
* Set session token
*
* @param {String} session token
* @return {Promise}
*/
setSessionToken: function(sessionToken, callback) {
var cb = callback || angular.noop;
$localStorage.token = sessionToken;
currentUser = User.get(cb);
}
};
});
2 changes: 1 addition & 1 deletion app/templates/karma.conf.js
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ module.exports = function(config) {
'client/bower_components/angular/angular.js',
'client/bower_components/angular-mocks/angular-mocks.js',
'client/bower_components/angular-resource/angular-resource.js',
'client/bower_components/angular-cookies/angular-cookies.js',
'client/bower_components/ngstorage/ngStorage.js',
'client/bower_components/angular-sanitize/angular-sanitize.js',
'client/bower_components/angular-route/angular-route.js',<% if(filters.uibootstrap) { %>
'client/bower_components/angular-bootstrap/ui-bootstrap-tpls.js',<% } %>
2 changes: 1 addition & 1 deletion app/templates/server/api/user(auth)/user.controller.js
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@ exports.create = function (req, res, next) {
newUser.role = 'user';
newUser.save(function(err, user) {
if (err) return validationError(res, err);
var token = jwt.sign({_id: user._id }, config.secrets.session, { expiresInMinutes: 60*5 });
var token = jwt.sign({_id: user._id }, config.secrets.session, { expiresInMinutes: config.tokenDuration.session });
res.json({ token: token });
});
};
13 changes: 6 additions & 7 deletions app/templates/server/auth(auth)/auth.service.js
Original file line number Diff line number Diff line change
@@ -56,21 +56,20 @@ function hasRole(roleRequired) {
/**
* Returns a jwt token signed by the app secret
*/
function signToken(id) {
return jwt.sign({ _id: id }, config.secrets.session, { expiresInMinutes: 60*5 });
function signToken(id, role, expiresInMinutes) {
return jwt.sign({ _id: id, role : role }, config.secrets.session, { expiresInMinutes: expiresInMinutes });
}

/**
* Set token cookie directly for oAuth strategies
*/
function setTokenCookie(req, res) {
function setToken(req, res) {
if (!req.user) return res.json(404, { message: 'Something went wrong, please try again.'});
var token = signToken(req.user._id, req.user.role);
res.cookie('token', JSON.stringify(token));
res.redirect('/');
var token = signToken(req.user._id, req.user.role, config.tokenDuration.session);
res.redirect('/login/'+token);
}

exports.isAuthenticated = isAuthenticated;
exports.hasRole = hasRole;
exports.signToken = signToken;
exports.setTokenCookie = setTokenCookie;
exports.setToken = setToken;
Original file line number Diff line number Diff line change
@@ -16,6 +16,6 @@ router
.get('/callback', passport.authenticate('facebook', {
failureRedirect: '/signup',
session: false
}), auth.setTokenCookie);
}), auth.setToken);

module.exports = router;
Original file line number Diff line number Diff line change
@@ -19,6 +19,6 @@ router
.get('/callback', passport.authenticate('google', {
failureRedirect: '/signup',
session: false
}), auth.setTokenCookie);
}), auth.setToken);

module.exports = router;
Original file line number Diff line number Diff line change
@@ -15,6 +15,6 @@ router
.get('/callback', passport.authenticate('twitter', {
failureRedirect: '/signup',
session: false
}), auth.setTokenCookie);
}), auth.setToken);

module.exports = router;
2 changes: 1 addition & 1 deletion app/templates/server/config/_local.env.js
Original file line number Diff line number Diff line change
@@ -20,4 +20,4 @@ module.exports = {
<% } %>
// Control debug level for modules using visionmedia/debug
DEBUG: ''
};
};
6 changes: 5 additions & 1 deletion app/templates/server/config/environment/index.js
Original file line number Diff line number Diff line change
@@ -29,6 +29,10 @@ var all = {
session: '<%= _.slugify(_.humanize(appname)) + '-secret' %>'
},

tokenDuration : {
session: 60 * 24 * 30
},

// List of user roles
userRoles: ['guest', 'user', 'admin'],

@@ -64,4 +68,4 @@ var all = {
// ==============================================
module.exports = _.merge(
all,
require('./' + process.env.NODE_ENV + '.js') || {});
require('./' + process.env.NODE_ENV + '.js') || {});
2 changes: 1 addition & 1 deletion test/fixtures/bower.json
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
"bootstrap-sass-official": "~3.1.1",
"bootstrap": "~3.1.1",
"angular-resource": ">=1.2.*",
"angular-cookies": ">=1.2.*",
"ngstorage": "~0.3.0",
"angular-sanitize": ">=1.2.*",
"angular-route": ">=1.2.*",
"angular-bootstrap": "~0.11.0",