Better password security
This commit is contained in:
parent
d6e74efe0e
commit
84bcb05fdd
5 changed files with 23 additions and 13 deletions
4
.vscode/launch.json
vendored
4
.vscode/launch.json
vendored
|
@ -6,7 +6,7 @@
|
||||||
"type": "dart-cli",
|
"type": "dart-cli",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"debugSettings": "${command.debugSettings}",
|
"debugSettings": "${command:debugSettings}",
|
||||||
"program": "${workspaceRoot}/bin/server.dart",
|
"program": "${workspaceRoot}/bin/server.dart",
|
||||||
"args": []
|
"args": []
|
||||||
},
|
},
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
"type": "dart-cli",
|
"type": "dart-cli",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"debugSettings": "${command.debugSettings}",
|
"debugSettings": "${command:debugSettings}",
|
||||||
"program": "${workspaceRoot}/bin/multi_server.dart",
|
"program": "${workspaceRoot}/bin/multi_server.dart",
|
||||||
"args": []
|
"args": []
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ library angel.models.user;
|
||||||
import 'package:angel_framework/common.dart';
|
import 'package:angel_framework/common.dart';
|
||||||
|
|
||||||
class User extends Model {
|
class User extends Model {
|
||||||
String email, username, password;
|
String email, username, password, salt;
|
||||||
final List<String> roles = [];
|
final List<String> roles = [];
|
||||||
|
|
||||||
User(
|
User(
|
||||||
|
@ -11,6 +11,7 @@ class User extends Model {
|
||||||
this.email,
|
this.email,
|
||||||
this.username,
|
this.username,
|
||||||
this.password,
|
this.password,
|
||||||
|
this.salt,
|
||||||
Iterable<String> roles: const []}) {
|
Iterable<String> roles: const []}) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.roles.addAll(roles ?? []);
|
this.roles.addAll(roles ?? []);
|
||||||
|
|
|
@ -13,12 +13,15 @@ class AuthController extends Controller {
|
||||||
/// Attempt to log a user in
|
/// Attempt to log a user in
|
||||||
LocalAuthVerifier localVerifier(UserService userService) {
|
LocalAuthVerifier localVerifier(UserService userService) {
|
||||||
return (String username, String password) async {
|
return (String username, String password) async {
|
||||||
List<User> users = await userService.index({'query':{'username': username}});
|
List<User> users = await userService.index({
|
||||||
|
'query': {'username': username}
|
||||||
|
});
|
||||||
|
|
||||||
if (users.isNotEmpty) {
|
if (users.isNotEmpty) {
|
||||||
var hash = hashPassword(password);
|
return users.firstWhere((user) {
|
||||||
return users.firstWhere((user) => user.password == hash,
|
var hash = hashPassword(password, user.salt, app.jwt_secret);
|
||||||
orElse: () => null);
|
return user.username == username && user.password == hash;
|
||||||
|
}, orElse: () => null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -29,8 +32,8 @@ class AuthController extends Controller {
|
||||||
auth = new AngelAuth(jwtKey: app.jwt_secret)
|
auth = new AngelAuth(jwtKey: app.jwt_secret)
|
||||||
..serializer = serializer
|
..serializer = serializer
|
||||||
..deserializer = deserializer
|
..deserializer = deserializer
|
||||||
..strategies.add(
|
..strategies.add(new LocalAuthStrategy(
|
||||||
new LocalAuthStrategy(localVerifier(app.container.make(UserService))));
|
localVerifier(app.container.make(UserService))));
|
||||||
|
|
||||||
await super.call(app);
|
await super.call(app);
|
||||||
await app.configure(auth);
|
await app.configure(auth);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:angel_common/angel_common.dart';
|
import 'package:angel_common/angel_common.dart';
|
||||||
import 'package:crypto/crypto.dart' show sha256;
|
import 'package:crypto/crypto.dart' show sha256;
|
||||||
import 'package:mongo_dart/mongo_dart.dart';
|
import 'package:mongo_dart/mongo_dart.dart';
|
||||||
|
import 'package:random_string/random_string.dart' as rs;
|
||||||
import '../models/user.dart';
|
import '../models/user.dart';
|
||||||
import '../validators/user.dart';
|
import '../validators/user.dart';
|
||||||
export '../models/user.dart';
|
export '../models/user.dart';
|
||||||
|
@ -15,14 +16,18 @@ configureServer(Db db) {
|
||||||
service.beforeCreated
|
service.beforeCreated
|
||||||
..listen(validateEvent(CREATE_USER))
|
..listen(validateEvent(CREATE_USER))
|
||||||
..listen((e) {
|
..listen((e) {
|
||||||
e.data['password'] = hashPassword(e.data['password']);
|
var salt = rs.randomAlphaNumeric(12);
|
||||||
|
e.data
|
||||||
|
..['password'] =
|
||||||
|
hashPassword(e.data['password'], salt, app.jwt_secret)
|
||||||
|
..['salt'] = salt;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SHA-256 hash any string, particularly a password.
|
/// SHA-256 hash any string, particularly a password.
|
||||||
String hashPassword(String password) =>
|
String hashPassword(String password, String salt, String pepper) =>
|
||||||
sha256.convert(password.codeUnits).toString();
|
sha256.convert(('$salt:$password:$pepper').codeUnits).toString();
|
||||||
|
|
||||||
/// Manages users.
|
/// Manages users.
|
||||||
///
|
///
|
||||||
|
|
|
@ -7,4 +7,5 @@ final Validator USER = new Validator({
|
||||||
});
|
});
|
||||||
|
|
||||||
final Validator CREATE_USER = USER.extend({})
|
final Validator CREATE_USER = USER.extend({})
|
||||||
..requiredFields.addAll(['email', 'username', 'password']);
|
..requiredFields.addAll(['email', 'username', 'password'])
|
||||||
|
..forbiddenFields.addAll(['salt', 'roles']);
|
||||||
|
|
Loading…
Reference in a new issue