Example remote method of User gets 401 Authorization Required

1,845 views
Skip to first unread message

Leo B

unread,
Feb 26, 2015, 1:34:42 PM2/26/15
to loopb...@googlegroups.com
To reproduce problem we are using example of issue #763 https://github.com/strongloop/loopback/issues/763 .

Question is whether this basic example works for anyone?

If not, what is missing, maybe an ACL setting or fix?

As suggested in /server/boot/userRemoteMethods.js we put

module.exports = function(app) {
 
var User = app.models.User;

 
User.greet = function(msg, cb) {
    cb
(null, 'Greetings... ' + msg);
 
}

 
User.remoteMethod(
   
'greet',
   
{
      isStatic
: true,
      accepts
: {arg: 'msg', type: 'string'},
      returns
: {arg: 'greeting', type: 'string'},
      http
: { verb: 'get', path: '/greet' }
   
}
 
);
};


Fails with 401 Authorization Required no matter which small variations we apply, without or with isStatic: true etc.

As mentioned, using HTTP GET to test with a proven good token in the URL

http://127.0.0.1:3000/api/Users/greet?msg=%22Joe%22&access_token=QqU0tx...

Per suggestion ran with DEBUG=loopback*,strong-remoting* and get this log:

  loopback:connector:mongodb MongoDB connection is established: mongodb://127.0.0.1:27017/sndb4 +362ms
express deprecated req
.param(name): Use req.params, req.body, or req.query instead node_modules/loopback/common/models/access-token.js:174:16
  loopback
:connector:mongodb all +5m AccessToken { where: { id: 'QqU0tx...' },
  limit
: 1,
  offset
: 0,
  skip
: 0 }
  loopback
:connector:mongodb all +11ms AccessToken { where: { _id: 'QqU0tx...' },
  limit
: 1,
  offset
: 0,
  skip
: 0,
  order
: [ 'id' ] } null [ { _id: 'QqU0tx...',
    ttl
: 1209600,
    created
: Mon Feb 23 2015 16:40:41 GMT-0800 (PST),
    userId
: '972294...' } ]
  loopback
:connector:mongodb all +3ms User { where: { id: '972294...' },
  limit
: 1,
  offset
: 0,
  skip
: 0 }
  loopback
:connector:mongodb all +1ms User { where: { _id: '972294...' },
  limit
: 1,
  offset
: 0,
  skip
: 0,
  order
: [ 'id' ] } null [ { _id: '972294...',
    realm
: null,
    username
: 'joe',
    password
: '----------------------------------------',
    credentials
: null,
    challenges
: null,
    email
: '---------@------------.---',
    emailVerified
: null,
    verificationToken
: null,
    status
: null,
    created
: null,
    lastUpdated
: null } ]
  strong
-remoting:rest-adapter remoting options: {"context":{"enableHttpContext":true},"rest":{"normalizeHttpPath":false,"xml":false},"json":{"strict":false,"limit":"100kb"},"urlencoded":{"extended":true,"limit":"100kb"},"cors":{"origin":true,"credentials":true,"methods":"GET,HEAD,PUT,PATCH,POST,DELETE"},"errorHandler":{"disableStackTrace":false}} +5m
  strong
-remoting:rest-adapter registering REST handler for class "User" +1ms
  strong
-remoting:rest-adapter     method User.prototype.__findById__accessTokens +0ms
  strong
-remoting:rest-adapter     method User.prototype.__destroyById__accessTokens +0ms
  strong
-remoting:rest-adapter     method User.prototype.__updateById__accessTokens +0ms
  strong
-remoting:rest-adapter     method User.prototype.__get__accessTokens +0ms
  strong
-remoting:rest-adapter     method User.prototype.__create__accessTokens +0ms
  strong
-remoting:rest-adapter     method User.prototype.__delete__accessTokens +0ms
  strong
-remoting:rest-adapter     method User.prototype.__count__accessTokens +0ms
  strong
-remoting:rest-adapter     method User.create +0ms
  strong
-remoting:rest-adapter     method User.upsert +0ms
  strong
-remoting:rest-adapter     method User.exists +1ms
  strong
-remoting:rest-adapter     method User.findById +0ms
  strong
-remoting:rest-adapter     method User.find +0ms
  strong
-remoting:rest-adapter     method User.findOne +0ms
  strong
-remoting:rest-adapter     method User.updateAll +0ms
  strong
-remoting:rest-adapter     method User.deleteById +0ms
  strong
-remoting:rest-adapter     method User.count +0ms
  strong
-remoting:rest-adapter     method User.prototype.updateAttributes +0ms
  strong
-remoting:rest-adapter     method User.login +0ms
  strong
-remoting:rest-adapter     method User.logout +0ms
  strong
-remoting:rest-adapter     method User.confirm +0ms
  strong
-remoting:rest-adapter     method User.resetPassword +0ms
  strong
-remoting:rest-adapter     method User.greet +0ms
  strong
-remoting:rest-adapter         put /:id/accessTokens/:fk restPrototypeMethodHandler +1ms
  strong
-remoting:rest-adapter         put /:id restPrototypeMethodHandler +0ms
  strong
-remoting:rest-adapter         put / restStaticMethodHandler +0ms
  strong
-remoting:rest-adapter         post /login restStaticMethodHandler +0ms
  strong
-remoting:rest-adapter         post /reset restStaticMethodHandler +0ms
  strong
-remoting:rest-adapter         post /update restStaticMethodHandler +0ms
  strong
-remoting:rest-adapter         post /:id/accessTokens restPrototypeMethodHandler +0ms
  strong
-remoting:rest-adapter         post / restStaticMethodHandler +0ms
  strong
-remoting:rest-adapter         head /:id restStaticMethodHandler +1ms
  strong
-remoting:rest-adapter         get /confirm restStaticMethodHandler +0ms
  strong
-remoting:rest-adapter         get /count restStaticMethodHandler +0ms
  strong
-remoting:rest-adapter         get /findOne restStaticMethodHandler +0ms
  strong
-remoting:rest-adapter         get /greet restStaticMethodHandler +0ms
  strong
-remoting:rest-adapter         get /:id/accessTokens/count restPrototypeMethodHandler +0ms
  strong
-remoting:rest-adapter         get /:id/accessTokens/:fk restPrototypeMethodHandler +0ms
  strong
-remoting:rest-adapter         get /:id/accessTokens restPrototypeMethodHandler +1ms
  strong
-remoting:rest-adapter         get /:id/exists restStaticMethodHandler +0ms
  strong
-remoting:rest-adapter         get /:id restStaticMethodHandler +0ms
  strong
-remoting:rest-adapter         get / restStaticMethodHandler +0ms
  strong
-remoting:rest-adapter         delete /:id/accessTokens/:fk restPrototypeMethodHandler +0ms
  strong
-remoting:rest-adapter         delete /:id/accessTokens restPrototypeMethodHandler +0ms
  strong
-remoting:rest-adapter         del /:id restStaticMethodHandler +0ms
  strong
-remoting:rest-adapter         all /logout restStaticMethodHandler +0ms
  strong
-remoting:rest-adapter     at /Users +1ms
express deprecated req
.param(name): Use req.params, req.body, or req.query instead node_modules/loopback/node_modules/strong-remoting/lib/http-context.js:142:18
express deprecated req
.param(name): Use req.params, req.body, or req.query instead node_modules/loopback/node_modules/strong-remoting/lib/http-context.js:153:22
express deprecated req
.param(name): Use req.params, req.body, or req.query instead node_modules/loopback/node_modules/strong-remoting/lib/http-context.js:153:59
express deprecated req
.param(name): Use req.params, req.body, or req.query instead node_modules/loopback/lib/application.js:299:60
  loopback
:connector:mongodb all +18ms ACL { where:
   
{ model: 'User',
     property
: { inq: [Object] },
     accessType
: { inq: [Object] } } }
  loopback
:connector:mongodb all +3ms ACL { where:
   
{ model: 'User',
     property
: { inq: [Object] },
     accessType
: { inq: [Object] } },
  order
: [ 'id' ] } null []
  loopback
:security:role isInRole(): $everyone +5m
  loopback
:security:access-context ---AccessContext--- +0ms
  loopback
:security:access-context principals: +1ms
  loopback
:security:access-context principal: {"type":"USER","id":"972294..."} +0ms
  loopback
:security:access-context modelName User +0ms
  loopback
:security:access-context modelId undefined +0ms
  loopback
:security:access-context property greet +0ms
  loopback
:security:access-context method greet +0ms
  loopback
:security:access-context accessType READ +0ms
  loopback
:security:access-context accessToken: +0ms
  loopback
:security:access-context   id "QqU0tx..." +0ms
  loopback
:security:access-context   ttl 1209600 +0ms
  loopback
:security:access-context getUserId() 972294... +0ms
  loopback
:security:access-context isAuthenticated() true +0ms
  loopback
:security:role Custom resolver found for role $everyone +1ms
  loopback
:security:acl The following ACLs were searched:  +0ms
  loopback
:security:acl ---ACL--- +0ms
  loopback
:security:acl model User +0ms
  loopback
:security:acl property * +0ms
  loopback
:security:acl principalType ROLE +0ms
  loopback
:security:acl principalId $everyone +0ms
  loopback
:security:acl accessType * +0ms
  loopback
:security:acl permission DENY +0ms
  loopback
:security:acl with score: +0ms 7495
  loopback
:security:acl ---Resolved--- +1ms
  loopback
:security:access-context ---AccessRequest--- +0ms
  loopback
:security:access-context  model User +0ms
  loopback
:security:access-context  property greet +0ms
  loopback
:security:access-context  accessType READ +0ms
  loopback
:security:access-context  permission DENY +0ms
  loopback
:security:access-context  isWildcard() false +0ms
  loopback
:security:access-context  isAllowed() false +0ms
  strong
-remoting:rest-adapter Error in GET /Users/greet?msg=%22Joe%22&access_token=QqU0tx...: Error: Authorization Required
    at app
.enableAuth.isAuthEnabled (/home/joeb/project17/node_modules/loopback/lib/application.js:327:21)
    at
Model.checkAccess (/home/joeb/project17/node_modules/loopback/lib/model.js:295:5)
    at
module.exports.ACL.checkAccessForContext (/home/joeb/project17/node_modules/loopback/common/models/acl.js:437:23)
    at _asyncMap
(/home/joeb/project17/node_modules/loopback/node_modules/async/lib/async.js:254:17)
    at
done (/home/joeb/project17/node_modules/loopback/node_modules/async/lib/async.js:135:19)
    at _toString
(/home/joeb/project17/node_modules/loopback/node_modules/async/lib/async.js:32:16)
    at _asyncMap
(/home/joeb/project17/node_modules/loopback/node_modules/async/lib/async.js:251:21)
    at results
(/home/joeb/project17/node_modules/loopback/node_modules/async/lib/async.js:575:34)
    at
module.exports.ACL.checkAccessForContext.find.async.parallel.resolved.permission (/home/joeb/project17/node_modules/loopback/common/models/acl.js:420:17)
    at
module.exports.Role.isInRole.resolver (/home/joeb/project17/node_modules/loopback/common/models/role.js:219:21) +13ms


We are running on what looks like a normal healthy server.

Raymond Feng

unread,
Feb 26, 2015, 2:23:40 PM2/26/15
to Leo B, loopb...@googlegroups.com
Add the following ACLs to the ‘User’ model in server/model-config.json:

“acls”: [
  {
     “principalType”: “ROLE”,
     “principalId”: “$everyone”,
     “permission”: “ALLOW”,
     “property”: “greet"
  }
]

Thanks,

---
Raymond Feng
Co-Founder and Architect @ StrongLoop, Inc.

StrongLoop makes it easy to develop APIs in Node, plus get DevOps capabilities like monitoring, debugging and clustering.

--
You received this message because you are subscribed to the Google Groups "LoopbackJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to loopbackjs+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Leo B

unread,
Feb 26, 2015, 3:55:56 PM2/26/15
to loopb...@googlegroups.com, srgui...@nrvr.com
Confirming that above posted acl by Raymond fixes it.

Rand McKinney

unread,
Feb 26, 2015, 6:01:05 PM2/26/15
to loopb...@googlegroups.com, srgui...@nrvr.com
If you just want an example of a remote method that doesn't require modifying ACLs, see the docs: http://docs.strongloop.com/display/LB/Remote+methods#Remotemethods-Example.

Rand
Reply all
Reply to author
Forward
0 new messages