AuthController.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <?php
  2. namespace App\Controllers\Api;
  3. use App\Models\UserModel;
  4. use App\Utils\Env;
  5. use App\Utils\Jwt;
  6. use App\Utils\Password;
  7. use PH7\JustHttp\StatusCode;
  8. use Respect\Validation\Exceptions\NestedValidationException;
  9. use Respect\Validation\Validator as v;
  10. class AuthController
  11. {
  12. /*
  13. * Obtiene las reglas de validación.
  14. */
  15. private function getValidationRules()
  16. {
  17. return [
  18. 'email' => v::stringType()->notEmpty()->email()->length(4, 255, true),
  19. 'username' => v::stringType()->notEmpty()->alnum()->length(4, 32, true),
  20. 'password' => v::stringType()->notEmpty()->graph()->length(8, 64, true)
  21. ];
  22. }
  23. /*
  24. * Inicia la sesión de un usuario.
  25. */
  26. public function login($req, $res)
  27. {
  28. $data = [];
  29. // Obtiene los campos del cuerpo de la petición.
  30. foreach (['nickname', 'password'] as $field) {
  31. if (v::key($field, v::notOptional(), true)->validate($req->body)) {
  32. $data[$field] = $req->body[$field];
  33. }
  34. }
  35. $rules = $this->getValidationRules();
  36. $identifyBy = 'username';
  37. // Comprueba el modo de autenticación.
  38. if (v::key('nickname', $rules['email'], true)->validate($data)) {
  39. $identifyBy = 'email';
  40. $data['nickname'] = strtolower($data['nickname']);
  41. }
  42. // Comprueba los campos del cuerpo de la petición.
  43. try {
  44. v::key('nickname', $rules[$identifyBy], true)
  45. ->key('password', $rules['password'], true)
  46. ->assert($data);
  47. } catch (NestedValidationException $e) {
  48. $res->status(StatusCode::BAD_REQUEST)->json([
  49. 'validations' => $e->getMessages()
  50. ]);
  51. }
  52. // Consulta la información del usuario que intenta autenticarse.
  53. $userAuth = UserModel::factory()
  54. ->select('id, password, active')
  55. ->where($identifyBy, $data['nickname'])
  56. ->where('active', true)
  57. ->first();
  58. // Comprueba la contraseña del usuario.
  59. if (empty($userAuth) || !Password::verify($data['password'], $userAuth['password'])) {
  60. $res->status(StatusCode::UNAUTHORIZED)->json([
  61. 'error' => 'Access credentials are invalid'
  62. ]);
  63. }
  64. // Genera el token de autenticación.
  65. $token = (new Jwt())->encode([
  66. 'iss' => Env::get('APP_NAME'),
  67. 'sub' => $userAuth['id'],
  68. 'aud' => Env::get('APP_URL'),
  69. 'exp' => strtotime('tomorrow'), // 24 horas
  70. 'iat' => strtotime('now')
  71. ]);
  72. $res->json([
  73. 'data' => [
  74. 'token' => $token
  75. ]
  76. ]);
  77. }
  78. /*
  79. * Consulta la información del usuario autenticado.
  80. */
  81. public function me($req, $res)
  82. {
  83. $userAuth = $req->app->local('userAuth');
  84. // Consulta la información del usuario autenticado.
  85. $userAuth = UserModel::factory()
  86. ->select('id, username, email, active, is_admin, created_at, updated_at')
  87. ->find($userAuth['id']);
  88. $res->json([
  89. 'data' => $userAuth
  90. ]);
  91. }
  92. }