Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using JWT for Loopback authentication

I'm trying to understand how I can fit a custom JWT routing into loopbacks security model. My application has an authentication "dance" involving SMS that results in a valid JWT token using the excellent description. I'm using the jsonwebtoken and things work as expected. After obtaining the token my angular.js client sends the token with each request in the Authorisation: JWT ..token.. header (found conflicting documentation, one says JWT, one Bearer, but I can figure that out).

Now I want to make use of the token inside a loopback application. I'd like to use the ACL system loopback provides. I did read the following resources:

  • Authenticate a Node.js API with JSON Web Tokens
  • Loopback, loggin in users
  • Third-party login (Passport)
  • Loopback, making authenticated requests
  • Passport strategy for JWT
  • Loopback OAuth2.0 source
  • Loopback satelizer

And I'm not clear what my next steps are. I have working:

  • User 'login' - generating a JWT
  • User login using username/password (to be retired)
  • Working ACL implementation in loopback (when I access an ACL protected resource I get, as expected a 4xx error)
  • My JWT token properly (?) in the header of the request

I need:

  • based on the JWT token a valid user with roles compatible to loopback ACL

Help is very much appreciated

like image 638
stwissel Avatar asked Dec 26 '15 18:12

stwissel


People also ask

Can JWT be used for authentication?

To authenticate a user, a client application must send a JSON Web Token (JWT) in the authorization header of the HTTP request to your backend API. API Gateway validates the token on behalf of your API, so you don't have to add any code in your API to process the authentication.

Is JWT good for authentication or authorization?

Both API key and JWT are used for authentication and authorization, but they do it differently. Authentication allows the user or application to use one or more methods of the API. Authorization defines how they can use those methods.

How JWT token works for authentication?

Secure: JWTs are digitally signed using either a secret (HMAC) or a public/private key pair (RSA or ECDSA) which safeguards them from being modified by the client or an attacker. Stored only on the client: You generate JWTs on the server and send them to the client. The client then submits the JWT with every request.

Should I use JWT for login?

JWTs can be used as an authentication mechanism that does not require a database. The server can avoid using a database because the data store in the JWT sent to the client is safe.


1 Answers

The solution turned out to be much simpler that I though it would be. For starters loopback does use its own jwt webtokens to keep a (stateless) user session. After establishing identity (in my case extracting the mobile number from my JWT token) I just need to lookup the member and generate the loopback native JWT token. My endpoint definition was this:

  Member.remoteMethod(
    'provideSMSToken', {
      accepts: [{
        arg: 'mobilenumber',
        type: 'string',
        description: 'Phone number including +65 and no spaces'
      }, {
        arg: 'token',
        type: 'string',
        description: 'the token received through SMS'
      }],
      returns: {
        arg: 'token',
        type: 'string'
      },
      description: 'provide SMS token to confirm login',
      http: {
        path: '/smsauthenticate',
        verb: 'post'
      },
      isStatic: true
    }

  );

and the provideSMSToken function like that:

 // Exchange the SMS Token with a login token
  Member.provideSMSToken = function(mobilenumber, token, cb) {
    var app = Member.app;
    // CHeck if the token does exist for the given phone number
    // if yes, check for the respective memeber

    if (!app.smsVerificationToken || !app.smsVerificationToken[mobilenumber] || app.smsVerificationToken[mobilenumber] !== token) {
      var wrongToken = new Error("Wrong or missing token");
      cb(wrongToken, "Wrong or missing token");
    } else {
      var timetolive = 86400;
      Member.lookupByPhone(mobilenumber, function(err, theOne) {
        if (err) {
          cb(err, "Sorry, no such member here!");
        } else {
          // We can provide a token now for authentication
          // using the default createAccessToken method
          theOne.createAccessToken(timetolive, function(err, accesstoken) {
            cb(err, accesstoken);
          })
        }
      });
    }
  }

Works like a charm

like image 194
stwissel Avatar answered Sep 17 '22 19:09

stwissel