lynndylanhurley / ng-token-auth Goto Github PK
View Code? Open in Web Editor NEWToken based authentication module for angular.js.
License: Do What The F*ck You Want To Public License
Token based authentication module for angular.js.
License: Do What The F*ck You Want To Public License
After registering a new user, and clicking on the confirmation link, the user is not logged in and the events 'auth:email-confirmation-success' , 'auth:email-confirmation-error' don't work.
The server does confirm the user and I can log in manually after this.
There are no visible js errors. Here's the rails output.
Started GET "/api/auth/confirmation?confirmation_token=abAsBkDwUYW8K6zDPV2k" for 127.0.0.1 at 2014-08-23 17:13:52 -0300
Processing by DeviseTokenAuth::ConfirmationsController#show as HTML
Parameters: {"confirmation_token"=>"abAsBkDwUYW8K6zDPV2k"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."confirmation_token" = '58c57c0679304e4feec4e3aab44aef773bb5dc4cba577e3e05281120ea7f1e1c' ORDER BY "users"."id" ASC LIMIT 1
(0.1ms) begin transaction
SQL (0.5ms) UPDATE "users" SET "confirmation_token" = ?, "confirmed_at" = ?, "tokens" = ?, "updated_at" = ? WHERE "users"."id" = 7 [["confirmation_token", nil], ["confirmed_at", "2014-08-23 20:13:52.834105"], ["tokens", "{}"], ["updated_at", "2014-08-23 20:13:52.834758"]]
(174.7ms) commit transaction
(0.1ms) begin transaction
SQL (0.2ms) UPDATE "users" SET "confirmation_token" = ?, "tokens" = ?, "updated_at" = ? WHERE "users"."id" = 7 [["confirmation_token", "abAsBkDwUYW8K6zDPV2k"], ["tokens", "{\"rqqUfUebi27nfkms1Q95gg\":{\"token\":\"$2a$10$M7MLatfE53/oTzlAku7Z/.a8SKEZowRc0w3FIUnv1.4OeGKtDuHB.\",\"expiry\":1410034433}}"], ["updated_at", "2014-08-23 20:13:53.082659"]]
(161.1ms) commit transaction
Redirected to http://localhost:9000/?account_confirmation_success=true&client_id=rqqUfUebi27nfkms1Q95gg&expiry=1410034433&token=3soO5-IWmiuQEFXqPv96dQ&uid=xxx%40gmail.com#/users/new
Completed 302 Found in 415ms (ActiveRecord: 337.0ms)
I'm able to login (with login and password) (response is {signedIn: true, configName: "default"}
).
But when I send new request to server in header I have no authorization header with Bearer /token/. why?
Here is request:
$http.get('/user')
.then(function (resp) {
$scope.resp=resp;
}); //I get 401
Here is my config:
$authProvider.configure({
apiUrl: '/angular-token/api',
tokenValidationPath: '/auth/validate_token',
signOutUrl: '/auth/logout',
emailSignInPath: '/auth/login',
});
Where using satellizer I have authorization header with all requests.
Hi,
First off thank you for the great work!
I'm having issues understaning how validateUser() is supposed to work. I mean the documentation states that "This method returns a promise that will resolve if a user's auth token exists and is valid".
So I expected that, after a successful login, when the user's session is expired a successive call to validateUser() should find an expired token and emit events accordingly.
This doesn't seem to be the case.
Indeed, when the current session is expired the call to validateUser() will find both existing auth_headers and a user with the flag "signedIn" set to true! There's no roundtrip to the backend to check wether a token is expired or not.
Is that the expected behaviour of validateUser()?
Thanks in advance
When attempting to log in with Google using IE 10 on the live demo, I get stucked on the redirect_uri page
Isn't the postMessage "partially supported" (aka broken) on IE 10 ?
See the following :
http://stackoverflow.com/questions/16226924/is-cross-origin-postmessage-broken-in-ie10
Internet Explorer 8+ partially supports cross-document messaging: it currently works with iframes, but not new windows. Internet Explorer 10, however, will support MessageChannel. Firefox currently supports cross-document messaging, but not MessageChannel.
I might be doing something wrong but if I use ngResource methods, the token doesn't get passed to the server. If I use plain $http.get it does. Either way generates the same ajax GET call, but whatever ng-token-auth does to hook into $http doesn't seem to extend to ngResource. I tried with both latest angular 1.3rc0 and 1.2.23.
angular.module('spacetoolsApp')
.controller('OrganizationsCtrl', ['$scope', 'Organization', '$http', function ($scope, Organization, $http) {
// THIS NEXT LINE WORKS
$scope.organizations = $http.get('http://www.spacetools.org/api/organizations.json');
// THIS LINE DOESN'T SEND ACCESS TOKEN TO SERVER, THOUGH AJAX CALL IS THE SAME
$scope.organizations = Organization.query();
}]);
Hi, I'm trying to use ng-token-auth with devise_token_auth gem.
I got a problem when trying to register with angulajs. I got these two line:
Unpermitted parameters: confirm_success_url, config_name, registration
Unpermitted parameters: confirm_success_url, config_name, registration
Any idea ?
This is the logs :
Started POST "/auth" for 127.0.0.1 at 2014-10-15 14:17:57 +0200
Processing by DeviseTokenAuth::RegistrationsController#create as HTML
Parameters: {"email"=>"[email protected]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "confirm_success_url"=>"http://localhost:3000/", "config_name"=>"default", "registration"=>{"email"=>"[email protected]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "confirm_success_url"=>"http://localhost:3000/", "config_name"=>"default"}}
Unpermitted parameters: confirm_success_url, config_name, registration
Unpermitted parameters: confirm_success_url, config_name, registration
(0.1ms) begin transaction
(0.3ms) SELECT COUNT(*) FROM "users" WHERE "users"."provider" = 'email' AND "users"."email" = '[email protected]'
User Exists (0.3ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('[email protected]') LIMIT 1
(0.1ms) rollback transaction
Completed 403 Forbidden in 309ms (Views: 1.3ms | ActiveRecord: 6.4ms)
Thanks for your work.
The usage of $location.search() within the validateUser
function is unreliable, if you have $locationProvider.html5Mode equals false which is most likely the case if you are using the ionic framework.
For instance:
When clicking on the confirmation button, the browser is redirected to the following url:
http://localhost:8100/?account_confirmation_success=true &client_id=[client_id] &expiry=[expiry] &token=[token] &uid=[uid]
Inside the validateUser
function, the following will always return undefined
if ($location.search().token !== void 0) // Will always return undefined
since $location.search()
will return an empty object.
See angular/angular.js#7239 for more information
(This would also follow same naming as in $auth.updateAccount)
updatePassForm
in controller, but changePasswordForm
in template.It seems that the email with reset instructions has a link to the template PasswordReset rather than the template PasswordUpdate. It means that the user is presented with email instead of password to change.
Can the default mailer have link with PasswordUpdate instead, so password reset request can be tested out of the box ?
I think there is an error in the readme :)
In the Broadcast auth:password-change-error
In the documentation I can see:
$scope.$on('auth:registration-change-error', function(ev, reason) {
alert("Registration failed: " + reason.errors[0]);
});
I guess what you meant was? :
$scope.$on('auth:password-change-error', function(ev, reason) {
///
});
:)
I am trying to work ng-token-auth into my app. the $http.post call that i was using successfully using was:
$http.post(serviceBase + 'token', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
I am interested in passing a config object to the http post call via the submitLogin function.
Can we add a second optional parameter to your submitLogin that we can add to the post call as the config options or is there a way I can access the request headers property of the http object?
Hi together,
in the current implementation something doesn't work with email/password login. For example the authData from handleLoginResponse doesn't get persisted. So no header information (token, etc.) is stored and hence sent...
Best regards,
loxy
Is it possible to provide sample code package that without using coffeescript?
Hi there,
first of all thanks for your great work!
I have a question, whats the best way to check wether a user is logged in or not? Seems like the validateUser method doesn't work ...
Thanks,
Andi
I have an Angular site within a Rails app, but am unable to install 'ng-token-auth'. I have:
Get the error:
Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to:
Error: [$injector:modulerr] Failed to instantiate module ng-token-auth due to:
Error: [$injector:modulerr] Failed to instantiate module ngCookies due to:
Error: [$injec......2)
I was able to get the sign up page working but am getting an " Unpermitted parameters: session" error for the sign in page.
Hello,
I am attempting to use ng-token-auth with devise_token_auth and rails-api and I can't get it to work.
I was basically following instructions at https://www.airpair.com/ruby-on-rails-4/posts/authentication-with-angularjs-and-ruby-on-rails
I get this error attempting registration:
Started POST "/auth" for 127.0.0.1 at 2014-10-20 19:46:59 +0000
Processing by DeviseTokenAuth::RegistrationsController#create as HTML
Parameters: {"email"=>"[email protected]", "password"=>"abc123", "password_confirmation"=>"abc123", "confirm_success_url"=>"http://127.0.0.1:9000/?#/signup", "config_name"=>"default"}
Unpermitted parameters: confirm_success_url, config_name
Unpermitted parameters: confirm_success_url, config_name
(8.9ms) BEGIN
(28.6ms) SELECT COUNT(*) FROM "users" WHERE "users"."provider" = 'email' AND "users"."email" = '[email protected]'
(1.4ms) ROLLBACK
Completed 403 Forbidden in 678ms (Views: 7.5ms | ActiveRecord: 176.7ms)
I saw in issue #49 that the "unpermitted parameters" message is harmless, but the user still doesn't get created.
Thanks
-auth:success should be auth:login in the readme events code example. or did i miss something?
-$auth.validateToken is given as a method example title, but is immediately followed by a validateUser example. what's the reasoning for this?
Noticed that the following (JS dist) only returns the user ID upon success:
resolveDfd: function() {
this.dfd.resolve({
id: this.user.id
});
return $timeout(((function(_this) {
return function() {
_this.dfd = null;
if (!$rootScope.$$phase) {
return $rootScope.$digest();
}
};
})(this)), 0);
},
I'm working on some route resolvers that could be simplified if this returned the full user. Otherwise, I'd need to hook into the rootScope events or make a separate API call. Is there a particular reason for the object truncation, or am I going about this all wrong? Thanks!
It works fine with $auth.submitRegistration but not with $auth.submitLogin.
$scope.handleLoginBtnClick = function() {
$auth.submitLogin($scope.loginForm)
.then(function(resp) {
alert("success");
})
.catch(function(resp) {
alert("error");
});
};
This is what I get in my browser console
TypeError: Cannot read property 'resolve' of null
at Object.resolveDfd (http://localhost:3000/assets/ng-token-auth.js?body=1:311:23)
at Object.handleValidAuth (http://localhost:3000/assets/ng-token-auth.js?body=1:464:27)
at http://localhost:3000/assets/ng-token-auth.js?body=1:179:25
at http://localhost:3000/assets/angular.js?body=1:8114:11
at wrappedCallback (http://localhost:3000/assets/angular.js?body=1:11574:81)
at http://localhost:3000/assets/angular.js?body=1:11660:26
at Scope.$eval (http://localhost:3000/assets/angular.js?body=1:12703:28)
at Scope.$digest (http://localhost:3000/assets/angular.js?body=1:12515:31)
at Scope.$apply (http://localhost:3000/assets/angular.js?body=1:12807:24)
at done (http://localhost:3000/assets/angular.js?body=1:8380:45)
I can see that the login works well in the server, here is the rails server logs
Completed 200 OK in 572ms (Views: 2.0ms | ActiveRecord: 14.3ms)
I’m using your library for an ionic iPhone app and was wondering if we could have an option in the config for storing the auth_header
information inside $localstorage in lieu of $cookieStore.
For instance:
config = {
apiUrl: '/api’,
storage: ‘$localStorage’
}
and then call $injector to get the storage module or would this a too big of a hack?
I'm getting GET "http://localhost:9000/api/auth/validate_token 401 (Unauthorized)" when I'm navigating a public page and not logged in. Is this the normal behaviour?
Great stuff and very well documented
Trying to understand what you mean by this note in the documentation? If I am writing a SPA and using a BAAS for my datastore, are you saying that there is no access control available in the website?
Thanks
This is the error
Error: [$injector:unpr] Unknown provider: aProvider <- a <- $http <- $auth
Thanks
I would be nice to just do
$auth.destroyUser().then(function(){
$state.go('home');
}
and also clean the headers.
There are alot of unnecessary calls for $q.defer
.
For example
updateAccount: (params) ->
acctDfd = $q.defer()
$http.put(@apiUrl() + @getConfig().accountUpdatePath, params)
.success((resp) =>
angular.extend @user, @getConfig().handleAccountUpdateResponse(resp)
$rootScope.$broadcast('auth:account-update-success', resp)
acctDfd.resolve(resp)
)
.error((resp) ->
$rootScope.$broadcast('auth:account-update-error', resp)
acctDfd.reject(resp)
)
acctDfd.promise
Is equivalent to
updateAccount: (params) ->
$http.put(@apiUrl() + @getConfig().accountUpdatePath, params)
.success((resp) =>
angular.extend @user, @getConfig().handleAccountUpdateResponse(resp)
$rootScope.$broadcast('auth:account-update-success', resp)
return resp
)
.error((resp) ->
$rootScope.$broadcast('auth:account-update-error', resp)
return $q.reject(resp)
)
I can configure devise to allow a user to sign in with an unconfirmed account, but on the ng-token-auth side, it still won't let me do it.
Also, if the option is configured, the user should be signed in automatically.
did npm install
cd test
bower install
cd ..
gulp dev
and it still didn't work. This is what I got:
Error: File to import not found or unreadable: bootstrap-sass-official/assets/stylesheets/bootstrap.scss.
Load paths:
/Users/zane/ng-token-auth/test/app/styles
/Users/zane/ng-token-auth/test/app/bower_components
on line 5 of /Users/zane/ng-token-auth/test/app/styles/deps.scss
events.js:72
throw er; // Unhandled 'error' event
^
Error in plugin 'gulp-ruby-sass'
Error: File to import not found or unreadable: bootstrap-sass-official/assets/stylesheets/bootstrap.scss.
Load paths:
/Users/zane/ng-token-auth/test/app/styles
/Users/zane/ng-token-auth/test/app/bower_components
on line 5 of /Users/zane/ng-token-auth/test/app/styles/deps.scss
at ChildProcess.<anonymous> (/Users/zane/ng-token-auth/node_modules/gulp-ruby-sass/index.js:98:25)
at ChildProcess.EventEmitter.emit (events.js:98:17)
at maybeClose (child_process.js:753:16)
at Process.ChildProcess._handle.onexit (child_process.js:820:5)
Hey @lynndylanhurley -
Seeing something a bit odd which doesn't make any sense immediately. I have a single-page-app (no hard page-loads ever) on which I perform the following to produce state staleness in $rootScope.user
The same does not appear to be happening when logging out / logging back in with existing users.
Re-assigning $rootScope.user = @user
within handleValidAuth
seems to fix the underlying problem, but I don't see why the same corruption isn't happening on multiple login / logouts. Admittedly, I haven't jumped into it much, as relying on $auth.user
in my client code is sufficient to keep things in sync properly.
Might be sufficient to just eliminate $rootScope.user
and let people manually assign that value (if needed), rather than keep it in sync with $auth.user
.
I assume I'm just doing something wrong here.
When I try to write an Angular controller test, I get the following error:
TypeError: 'undefined' is not a function (evaluating 'this.handlePostMessage.bind(this)') at /Users/jasonswett/projects/ben_franklin_labs/lunch_hub/client/bower_components/ng-token-auth/dist/ng-token-auth.js:97
Is there some specific extra step I have to take to get ng-token-auth not to cause this error? I'm including other custom modules and those seem to work fine, so I'm kind of at a loss.
I'm submitting this as an issue rather than just a StackOverflow question or something in case it is actually a legitimate issue that needs to be addressed.
I want to use Your script for my app.
If I'm right Your script handles client side.
I have to design my API in PHP on server side.
Can You give ma a hint what PHP framework (script) should I use to handle data from Your script?
I apologize for what is most likely a very basic question. After a full week in some quite obscure parts of Satellizer, I realize either it, or my problem, are fatally flawed.
I have a Python-based REST API. I have an Angular frontend. Satellizer and Twitter auth are working fine, tokens etc., as long as the frontend and the backend are served from the same server/port.
My goal, though, is to move the frontend out of the backend, hence the desire to use tokens instead of cookies. Doing so, though, hits the "blocked a frame with origin from accessing a cross-origin frame" issue on the popups.
Is this something fundamental, or does ng-token-auth do things differently or provide a workaround (e.g. a proxy?)
@lynndylanhurley: is there a way to include additional form fields like First Name, Last Name while submitting registration? If I add additional form fields to the registration object, they are filtered out before POSTing to server.
Great library, btw, thanks very much.
After adding ng-token-auth and running the minify process (via grunt build), I receive this error:
Error: [$injector:unpr] Unknown provider: a
This only occurs when the files are minified. I'm currently using version 0.0.20-beta3.
If I remove references to ng-token-auth, everything works as expected (after minification).
I want to restrict access to the settings pages, so far I use this following code to do this:
.state('settings', {
url: "/settings",
abstract:true,
templateUrl: "settings/layout.html",
resolve: {
auth: function($auth) {
return $auth.validateUser();
}
}
})
.state('settings.account', {
url: '',
templateUrl: "settings/account.html"
})
The problem now, is when I refresh the settings page, I got logged out. But I clicked nowhere on logout.
Any idea ? Thank you
During sign-in (possibly others?) ng-token-auth seems to return the same "Invalid credentials" / "unauthorized" error in the rejected promise response, regardless of the up-stream authentication failure. If this is a result of a 500 server error, there's no way to know client-side, that the error was illegitimate and something that should be communicated to the end user. Providing a HTTP status code and/or a stacktrace (if using devise_token_auth?) in this situation could help in this regard.
Having some trouble implementing the password reset. My form for the password reset form mirrors your example code. My event listener looks like...
$rootScope.$on('auth:password-reset-prompt', function() {
console.log('reset password');
$state.go('password-reset');
});
That message isn't logged out to the console. The password reset state is set up properly in my routes. Looking at my server output, the parameters associated with the /auth/password POST request look like this...
Started POST "/auth/password" for 127.0.0.1 at 2014-07-18 10:39:51 -0400
Processing by DeviseTokenAuth::PasswordsController#create as HTML
Parameters: {
"email"=>"[email protected]", "redirect_url"=>"http://localhost:9000/?client_id=Nn6qRzJAsfMBF7XZgwjh_g&expiry=1406903819&reset_password=true&token=J3SWEcdBFCbI6ibRLBIDcQ&uid=test%40aol.com#/login",
"password"=>{"email"=>"[email protected]", "redirect_url"=>"http://localhost:9000/?client_id=Nn6qRzJAsfMBF7XZgwjh_g&expiry=1406903819&reset_password=true&token=J3SWEcdBFCbI6ibRLBIDcQ&uid=test%40aol.com#/login"}}
Can't verify CSRF token authenticity
Unpermitted parameters: password
Unpermitted parameters: password
Unpermitted parameters: password
As you can see, the params are getting passed in a second time under the password key. All my modules seem to be up to date. Any reason why password is included as a param? To clarify: The reset email is sending, but the event doesn't fire.
In your code when sign in you return data of resp.data
. My API returned object doesn't have data
attr. And it would be a night mare (somehow) to implement it. Temporarily, I'm hacking your code to make it works with me.
As well as this method: https://github.com/lynndylanhurley/ng-token-auth/blob/master/src/ng-token-auth.coffee#L87
Your validateUser() method has worked like a charm on the resolve property of states. On the flip side, I've been attempting to restrict access to some pubic routes after a user has been authenticated, such as a landing page. For my use case, it makes more sense that the base route "/" would redirect somewhere else (like a dashboard) instead of presenting the website landing page if a user is already authenticated.
So far my research into this subject has pointed toward using the "app.run()" method while setting a data property on the state. For example, this data property could read: "Public" or "Private." Then inside the run method, I could listen for $stateChangeStart and run a test like:
if ( toState.data.auth == 'Public' && $auth.isAuthenticated() ) {
// redirect or other stuff
}
If both were true I could redirect to another view, for instance. For this to work my custom method isAuthenticated would return a boolean value. I would use validateUser() but it returns a promise.
After some hacking, this code appears to work
.run(function($rootScope, $auth){
$rootScope.isAuthenticated = function() {
if ($auth.user.uid) {
return true;
} else {
return false;
}
};
$rootScope.$on('$stateChangeStart', function(event, toState){
if ( toState.data.auth === 'Public' && $rootScope.isAuthenticated() ) {
event.preventDefault();
return false;
}
});
})
.state('landing', {
url: '/',
templateUrl: 'views/main.html',
controller: 'MainCtrl',
data: { auth: 'Public'}
})
Getting:
NameError - undefined local variable or method
set_reset_password_token' for #User:0x007fa8c5c005d8:` when executing $auth.requestPasswordReset($scope.passwordResetRequestForm)
This is related to DeviseTokenAuth: devise_token_auth / app / models / devise_token_auth / concerns / user.rb
module DeviseTokenAuth::Concerns::User
extend ActiveSupport::Concern
Line 54-56
# override devise method to include additional info as opts hash
def send_reset_password_instructions(opts=nil)
token = set_reset_password_token
I want to send an extra parameter to my omniauth path, but I'm getting an ArgumentError: ArgumentError (bad argument (expected URI object or URI string))
...
authProviderPaths: {
linkedin: '/auth/linkedin?type=Candidate'
}
...
Any workaround for this?
What should I do to get this working with anonymous sessions?
Noticed some inconsistency in naming in the sign out method. Please see bold.
Furthermore, it would be great if it was either Login and Logout or Signin and Signout instead of the current naming with Login and Signout.
$auth.signOut
De-authenticate a user. This method does not take any arguments. This method will change the user's auth_token server-side, and it will destroy the uid and auth_token cookies saved client-side.
This method broadcasts the following events:
auth:logout-success
auth:logout-error
Example use in a controller:
angular.module('ngTokenAuthTestApp')
.controller('IndexCtrl', function($auth) {
$scope.handleSignOutBtnClick = function() {
$auth.signOut()
.then(function(resp) {
// handle success response
})
.catch(function(resp) {
// handle error response
});
};
});
JOSN Web Token
has a different authorization header format.
http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25
Its format is Bearer {token}
The token is a object's encoded string by server. the object contains the user's info, may include uid, name, etc.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.