ソースを参照

Rewrite authentication to be more sensible

Matt Coles 9 年 前
コミット
042f49b3de
共有5 個のファイルを変更した43 個の追加47 個の削除を含む
  1. 7 8
      README.md
  2. 17 31
      routes/user/login.js
  3. 6 3
      routes/user/register.js
  4. 8 0
      utils/auth-keys.js
  5. 5 5
      utils/route-manager.js

+ 7 - 8
README.md

@@ -62,19 +62,18 @@ The server will then respond with a JSON object that looks something like this:
62 62
 ```
63 63
 The value of the error code will be `1` if the username already exists.
64 64
 
65
-### /login/
65
+### /auth/
66 66
 In order to log into an account, or essentially request a new authentication
67 67
 token, a `POST` request should be sent with the following data:
68 68
 ```javascript
69 69
 {
70 70
     "user": "FooBar", // Username goes here
71
-    "password": "hunter2", // Optional field if auth-key is present
72
-    "auth-key": "$2a$10$.X9YrNyd2R7b2ycAumHn.ONiINs2bCkRDupugu6sjZkUkPmXSaSra" // Optional field if password is present
71
+    "password": "hunter2", // Password goes here
73 72
 }
74 73
 ```
75
-Using the auth-key will reset and generate a new authentication key, whereas
76
-password will simply get the current auth-key. In either case the following data
77
-will be returned:
74
+Using this will then generate a new authentication key, **invalidating** any
75
+existing authentication key for that account. Note that you do not need to use
76
+/auth/ after registering as a new auth key is already generated.
78 77
 ```javascript
79 78
 {
80 79
     "logged_in": 1, // Value is 1 or 0 whether or not the login was successful
@@ -83,5 +82,5 @@ will be returned:
83 82
 }
84 83
 ```
85 84
 The error codes are as follows, `1` indicates the username could not be found,
86
-`2` indicates that the password is invalid and `3` indicates the provided
87
-authentication key was invalid.
85
+`2` indicates that the password is invalid and `3` indicates that the login
86
+request was malformed.

+ 17 - 31
routes/user/login.js

@@ -1,6 +1,7 @@
1 1
 var Redis = require("ioredis");
2 2
 var redis = new Redis();
3 3
 var bcrypt = require('bcrypt-nodejs');
4
+var authgen = require("./../../utils/auth-keys.js");
4 5
 
5 6
 module.exports = {
6 7
   perform: function(a,b) {
@@ -10,49 +11,34 @@ module.exports = {
10 11
 
11 12
 var perform = function(req, res) {
12 13
   var username = req.body.user || req.query.user;
13
-  username = username.toLowerCase();
14 14
   var password = req.body.password || req.query.password;
15
-  var auth_key = req.body.auth_key || req.query.auth_key;
16 15
   var uquery   = 'user:' + username;
17 16
 
18 17
   redis.hgetall(uquery).then(function (result) {
19 18
     if (result.password && result !== undefined && result !== null) {
20 19
       var user_object = result;
21
-      if (auth_key !== "" && auth_key !== undefined && auth_key !== null) {
22
-        if (auth_key === user_object["auth-key"]) {
23
-          var timestamp_user = Date.now().toString() + username;
24
-          user_object["auth-key"] = bcrypt.hashSync(timestamp_user);
25
-          redis.set(uquery, "auth-key", user_object["auth-key"]);
26
-          res.send({"logged_in": 1,
27
-                   "auth-key": user_object["auth-key"],
28
-                   "error": 0});
29
-        } else {
30
-          res.send({"logged_in": 0,
31
-                   "error": 3});
32
-        }
33
-      } else {
34
-        bcrypt.compare(password, user_object["password"], function (err, matched) {
35
-          if (matched === true) {
36
-            if (undefined === user_object["auth-key"]) {
37
-              var timestamp_user = Date.now().toString() + username;
38
-              user_object["auth-key"] = bcrypt.hashSync(timestamp_user);
39
-              redis.set(uquery, JSON.stringify(user_object));
40
-              res.send({"logged_in": 1,
41
-                       "auth-key": user_object["auth-key"],
42
-                       "error": 0});
43
-            } else {
44
-              res.send({"logged_in": 1,
45
-                       "auth-key": user_object["auth-key"],
46
-                       "error": 0});
20
+      if (username && password) {
21
+        username = username.toLowerCase();
22
+        bcrypt.compare(password, user_object.password, function (err, matched) {
23
+          if (matched) {
24
+            var new_auth_key = authgen.generate(username);
25
+            var aquery = "auth-key:" + new_auth_key;
26
+            redis.set(aquery, username);
27
+            redis.hset(uquery, "auth-key", new_auth_key);
28
+            if (user_object["auth-key"]) {
29
+              redis.del("auth-key:" + user_object["auth-key"]);
47 30
             }
48
-            return;
31
+            res.send({"logged_in": 1,
32
+                     "auth-key": new_auth_key,
33
+                     "error": 0})
49 34
           } else {
50 35
             res.send({"logged_in": 0,
51 36
                      "error": 2});
52
-                     return;
53 37
           }
54 38
         });
55
-
39
+      } else {
40
+        res.send({"logged_in": 0,
41
+                 "error": 3});
56 42
       }
57 43
     } else {
58 44
       res.send({"logged_in": 0,

+ 6 - 3
routes/user/register.js

@@ -1,6 +1,6 @@
1 1
 var Redis = require("ioredis");
2 2
 var redis = new Redis();
3
-var bcrypt = require('bcrypt-nodejs');
3
+var authgen = require("./../../utils/auth-keys.js");
4 4
 
5 5
 module.exports = {
6 6
   perform: function(a,b) {
@@ -11,8 +11,9 @@ module.exports = {
11 11
 var perform = function (req, res) {
12 12
   var tmp_username = req.body.user || req.query.user;
13 13
   var tmp_password = req.body.password || req.query.password;
14
-  tmp_username = tmp_username.toLowerCase();
14
+  tmp_username     = tmp_username.toLowerCase();
15 15
   var uquery       = 'user:' + tmp_username;
16
+  var aquery       = "";
16 17
   var user_object  = {};
17 18
 
18 19
   redis.hgetall(uquery).then(function (result) {
@@ -22,9 +23,11 @@ var perform = function (req, res) {
22 23
     } else {
23 24
       bcrypt.hash(tmp_password, null, null, function (err, hash) {
24 25
         user_object["password"] = hash;
25
-        user_object["auth-key"] = bcrypt.hashSync(Date.now().toString() + tmp_username);
26
+        user_object["auth-key"] = authgen.generate(tmp_username);
27
+        aquery = "auth-key:" + user_object["auth-key"];
26 28
         redis.hset(uquery, "password", user_object.password);
27 29
         redis.hset(uquery, "auth-key", user_object["auth-key"]);
30
+        redis.set(aquery, tmp_username);
28 31
         res.send({"registered": 1,
29 32
                  "auth-key": user_object["auth-key"],
30 33
                  "error": 0});

+ 8 - 0
utils/auth-keys.js

@@ -0,0 +1,8 @@
1
+bcrypt = require("bcrypt-nodejs");
2
+
3
+module.exports = {
4
+  generate: function (user) {
5
+    var obfuscator = (Math.random()+1).toString(36).substring(7);
6
+    return bcrypt.hashSync(Date.now().toString() + user + obfuscator);
7
+  }
8
+}

+ 5 - 5
utils/route-manager.js

@@ -1,13 +1,13 @@
1 1
 var express = require("express");
2 2
 var router = express.Router();
3
-var hello = require("./routes/misc/helloworld.js");
4
-var register = require("./routes/user/register.js");
5
-var login = require("./routes/user/login.js");
3
+var hello = require("../routes/misc/helloworld.js");
4
+var register = require("../routes/user/register.js");
5
+var login = require("../routes/user/login.js");
6 6
 
7 7
 module.exports = router;
8 8
 
9 9
 router.get('/hello/(:name)?', hello.perform);
10 10
 
11
-router.all('/register', register.perform);
11
+router.all('/register/', register.perform);
12 12
 
13
-router.all('/login', login.perform);
13
+router.all('/auth/', login.perform);