17

I can't seem to find any good information about how to authenticate a user using Meteor's DDP.

Is this possible? If so, what's the best way to do it? How can you log in remotely to Meteor using SRP?

I'm currently using straight Node (eventually will use Express), along with this node ddp client.

gkoberger
  • 476
  • 4
  • 11

3 Answers3

35

To log in via DDP, simply send a method call. You alter it slightly depending on how you want to log in.

I'll use ddp-tools to try and explain how to log in, since it would be communicating with purely ddp. The login details in the below examples are

The username is user_1, password is qwerty (yeah I know its bad), and email address is email@email.com, the login token is MxNY9BFPKra2uNWG7

The format is

ddp call <method call name> [<param1>..]

Which is the same as doing ddpclient.call(<method call name>,<param1>,callback) in nodejs

To log in with email and password

ddp call 'login' '{"password":"qwerty","user":{"email":"email@email.com"}}'

To log in with a username and password

ddp call 'login' '{"password":"qwerty","user":{"username":"user_1"}}'

To log in with a token (what meteor saves when you log in:

ddp call 'login' '{"resume":"MxNY9BFPKra2uNWG7"}'

--

The difficult one: SRP

If you don't want to send the password in plain-text like the above way, you're not using a SSL secured/https connection you can use SRP.

To login with SRP its a little bit tricker as it has a couple of stages

1. Begin a passwordExchange to establish the key to communicate the hash
2. Send a login call with the hash calculated using the reply from 1)

Step 1:

-Begin a SRP password exchange:

ddp call 'beginPasswordExchange' '{"A":"A","user":{"email":"email@email.com"}}

The response will be something like

{"identity":"identity","salt":"salt","B":B"}

Then you can use this to login:

ddp call 'login' '{"srp":{"M":"srp hash"}}'

Similarly you can use the username instead of the email above.

So to get the values of M, and A you need an SRP library. Since there's an SRP library in meteor its easy to explain how to get the password from each, its quite tricky. If you want to write one in another language you could use wikipedia's explanation to build the methods out

So we begin an srp exchange (from the SRP library in meteors SRP package), since you're using node.js you could include all the files in your project (except package.js)

var srp = new SRP.Client(password);

This will give you A, then you will get back data that you can respond with:

var response = srp.respondToChallenge(result);

This will finally give you the SHA hash to reply with using 'M', taking in 'B' and the salt.

Finally

Don't forget to check the final response when you do log in to see if the result matches what it should be

srp.verifyConfirmation({HAMK: result.HAMK}

Again these are all from the SRP library in Meteor, but they're all part of the SRP spec as on wikipedia. Meteor's SRP uses SHA256 as the hashing function.

Examples:

Community
  • 1
  • 1
Tarang
  • 75,157
  • 39
  • 215
  • 276
  • 1
    I got SRP authentication working over DDP in node, code here if anyone's interested: https://github.com/emgee3/srp-test – emgee Nov 01 '13 at 20:40
  • @emgee nice work! I've altered the answer to include your link. – Tarang Nov 02 '13 at 01:39
  • Not relevant anymore, Meteor dropped SRP. – Mário May 05 '15 at 09:56
  • @Mário SRP can still be used in projects. It's not completely dropped. – Tarang May 05 '15 at 13:51
  • For older versions yes. Check this pad: https://meteor.hackpad.com/SRP-bcrypt-J5mdBojeVfe – Mário May 06 '15 at 02:56
  • 1
    @Mário I currently use it on Meteor 1.1.0.2. All it to work is an `srp` section under password where it can work alongside bcrypt. It doesn't take much effort to add in a hash. Any 3rd party ddp connection can still have the security bump srp offers. The argument for bcrypt was more for easier 3rd party compatibility as outlined the doc you have given a link to owing to the difficulty using srp. But it doesnt stop anyone from using srp today alongside bcrypt. – Tarang May 06 '15 at 05:20
  • What if we wanted to authenticate using oauth like facebook and google? – Suyash Feb 29 '16 at 17:53
3

A package is now doing the login part adding a loginWithPassowrd method to the DDP connection.

meteor add ongoworks:ddp-login

Then:

// Get the connection
var conn = DDP.connect(Meteor.absoluteUrl());

// Pass the connection to `DDP.loginWithPassword`, which is otherwise similar to
// the core `Meteor.loginWithPassword` method.
DDP.loginWithPassword(conn, {username: 'admin'}, 'admin', function (error) { ... })
Flavien Volken
  • 19,196
  • 12
  • 100
  • 133
2

Closest I've found is this, but it's in cryptic Objective-C :-P https://github.com/boundsj/ObjectiveDDP/blob/master/Example/Example/LoginViewController.m

The functions it calls are in C though: https://github.com/boundsj/ObjectiveDDP/blob/master/ObjectiveDDP/srp/srp.c

And Meteor's SRP unit test is here: https://github.com/meteor/meteor/blob/master/packages/srp/srp_tests.js

and the Meteor srp code is here: https://github.com/meteor/meteor/blob/master/packages/srp/srp.js

You'll need at least this: https://github.com/jedp/node-srp

Good luck. I'm trying to figure out how to do this in Java and it's more cryptic than most encryption schemes. Hardest part is figuring out how Meteor encodes the identity but that's in the Meteor srp code which you can probably lift since it's in Javascript :-)

kenyee
  • 2,309
  • 1
  • 24
  • 32