Authenticating with Meteor via DDP (and SRP?)

前端 未结 3 1430
-上瘾入骨i
-上瘾入骨i 2020-12-07 23:52

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

相关标签:
3条回答
  • 2020-12-08 00:20

    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:

    • Node JS - https://github.com/emgee3/srp-test
    0 讨论(0)
  • 2020-12-08 00:27

    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 :-)

    0 讨论(0)
  • 2020-12-08 00:42

    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) { ... })
    
    0 讨论(0)
提交回复
热议问题