myth-auth
myth-auth copied to clipboard
Exception in json post!
Hi, i implemented myth auth in a test api and when i try to create a new user via "application/json" i get an exception
{
"title": "ErrorException",
"type": "ErrorException",
"code": 500,
"message": "Undefined offset: 1",
"file": "/var/www/html/vendor/myth/auth/src/Authentication/Passwords/NothingPersonalValidator.php",
"line": 90,
"trace": [
{
"file": "/var/www/html/vendor/myth/auth/src/Authentication/Passwords/NothingPersonalValidator.php",
"line": 90,
"function": "errorHandler",
"class": "CodeIgniter\\Debug\\Exceptions",
"type": "->",
"args": [
8,
"Undefined offset: 1",
"/var/www/html/vendor/myth/auth/src/Authentication/Passwords/NothingPersonalValidator.php",
90,
{
"password": "[email protected]",
"user": [],
"userName": "",
"email": "",
"valid": true,
"needles": [
""
],
"localPart": ""
}
]
},
{
"file": "/var/www/html/vendor/myth/auth/src/Authentication/Passwords/NothingPersonalValidator.php",
"line": 39,
"function": "isNotPersonal",
"class": "Myth\\Auth\\Authentication\\Passwords\\NothingPersonalValidator",
"type": "->",
"args": [
"[email protected]",
[]
]
},
{
"file": "/var/www/html/vendor/myth/auth/src/Authentication/Passwords/PasswordValidator.php",
"line": 55,
"function": "check",
"class": "Myth\\Auth\\Authentication\\Passwords\\NothingPersonalValidator",
"type": "->",
"args": [
"[email protected]",
[]
]
},
{
"file": "/var/www/html/vendor/myth/auth/src/Authentication/Passwords/ValidationRules.php",
"line": 45,
"function": "check",
"class": "Myth\\Auth\\Authentication\\Passwords\\PasswordValidator",
"type": "->",
"args": [
"[email protected]",
[]
]
},
{
"file": "/var/www/html/vendor/codeigniter4/framework/system/Validation/Validation.php",
"line": 312,
"function": "strong_password",
"class": "Myth\\Auth\\Authentication\\Passwords\\ValidationRules",
"type": "->",
"args": [
"[email protected]",
null
]
},
{
"file": "/var/www/html/vendor/codeigniter4/framework/system/Validation/Validation.php",
"line": 159,
"function": "processRules",
"class": "CodeIgniter\\Validation\\Validation",
"type": "->",
"args": [
"password",
"password",
"[email protected]",
[
"required",
"strong_password"
],
{
"name": "rafael",
"lastname": "sonicne",
"email": "[email protected]",
"password": "[email protected]",
"cpassword": "[email protected]",
"DBGroup": null
}
]
},
{
"file": "/var/www/html/vendor/codeigniter4/framework/system/Controller.php",
"line": 183,
"function": "run",
"class": "CodeIgniter\\Validation\\Validation",
"type": "->",
"args": []
},
{
"file": "/var/www/html/app/Controllers/Api/V1/Users.php",
"line": 99,
"function": "validate",
"class": "CodeIgniter\\Controller",
"type": "->",
"args": [
{
"email": {
"rules": "required|valid_email|is_unique[users.email]",
"errors": {
"required": "O e-mail é necessário",
"valid_email": "Você deve inserir um email válido",
"is_unique": "Esse e-mail já está cadastrado"
}
},
"name": {
"rules": "required|min_length[2]",
"errors": {
"required": "Seu nome é necessário",
"min_length": "Seu nome deve ter pelo menos 2 caracteres"
}
},
"lastname": {
"rules": "required|min_length[2]",
"errors": {
"required": "Seu sobrenome é necessário",
"min_length": "Seu sobrenome deve ter pelo menos 2 caracteres"
}
},
"password": {
"rules": "required|strong_password",
"errors": {
"required": "A senha é necessário",
"strong_password": "Essa senha está facil demais"
}
},
"cpassword": {
"rules": "required|matches[password]",
"errors": {
"required": "Você não digitou a confirmação da senha",
"matches": "As senhas não são iguais"
}
}
}
]
},
{
"file": "/var/www/html/vendor/codeigniter4/framework/system/CodeIgniter.php",
"line": 928,
"function": "create",
"class": "App\\Controllers\\Api\\V1\\Users",
"type": "->",
"args": []
},
{
"file": "/var/www/html/vendor/codeigniter4/framework/system/CodeIgniter.php",
"line": 436,
"function": "runController",
"class": "CodeIgniter\\CodeIgniter",
"type": "->",
"args": [
{}
]
},
{
"file": "/var/www/html/vendor/codeigniter4/framework/system/CodeIgniter.php",
"line": 336,
"function": "handleRequest",
"class": "CodeIgniter\\CodeIgniter",
"type": "->",
"args": [
null,
{
"handler": "file",
"backupHandler": "dummy",
"storePath": "/var/www/html/writable/cache/",
"cacheQueryString": false,
"prefix": "",
"ttl": 60,
"file": {
"storePath": "/var/www/html/writable/cache/",
"mode": 416
},
"memcached": {
"host": "127.0.0.1",
"port": 11211,
"weight": 1,
"raw": false
},
"redis": {
"host": "127.0.0.1",
"password": null,
"port": 6379,
"timeout": 0,
"database": 0
},
"validHandlers": {
"dummy": "CodeIgniter\\Cache\\Handlers\\DummyHandler",
"file": "CodeIgniter\\Cache\\Handlers\\FileHandler",
"memcached": "CodeIgniter\\Cache\\Handlers\\MemcachedHandler",
"predis": "CodeIgniter\\Cache\\Handlers\\PredisHandler",
"redis": "CodeIgniter\\Cache\\Handlers\\RedisHandler",
"wincache": "CodeIgniter\\Cache\\Handlers\\WincacheHandler"
}
},
false
]
},
{
"file": "/var/www/html/public/index.php",
"line": 37,
"function": "run",
"class": "CodeIgniter\\CodeIgniter",
"type": "->",
"args": []
}
]
}
When I send the request through "multipart/form-data" I get the registration successfully!
I investigated the myth files to find a solution to this problem, but I couldn't.
Below are the classes I used as a test:
<?php
namespace App\Controllers\Api\V1;
use CodeIgniter\RESTful\ResourceController;
class Users extends ResourceController
{
protected $modelName = 'App\Models\UserModel';
protected $format = 'json';
public function create(){
$rules = [
'email' => [
'rules' => 'required|valid_email|is_unique[users.email]',
'errors' => [
'required' => 'O e-mail é necessário',
'valid_email' => 'Você deve inserir um email válido',
'is_unique' => 'Esse e-mail já está cadastrado',
],
],
'name' => [
'rules' => 'required|min_length[2]',
'errors' => [
'required' => 'Seu nome é necessário',
'min_length' => 'Seu nome deve ter pelo menos 2 caracteres',
],
],
'lastname' => [
'rules' => 'required|min_length[2]',
'errors' => [
'required' => 'Seu sobrenome é necessário',
'min_length' => 'Seu sobrenome deve ter pelo menos 2 caracteres',
],
],
'password' => [
'rules' => 'required|strong_password',
'errors' => [
'required' => 'A senha é necessário',
'strong_password' => 'Essa senha está facil demais',
],
],
'cpassword' => [
'rules' => 'required|matches[password]',
'errors' => [
'required' => 'Você não digitou a confirmação da senha',
'matches' => 'As senhas não são iguais',
],
],
];
if (! $this->validate($rules)){
return $this->respond([
'status' => 500,
'error' => true,
'message' => $this->validator->getErrors(),
'data' => []
],500);
}
die('registration ok');
}
}
Routes:
$routes->resource('api/v1/users');
Prints:
Codeigniter 4.1.3 PHP 7.3
I found the cause of the problem, I had to modify the buildUserFromRequest method in the /src/Authentication/Passwords/ValidationRules.php file
protected function buildUserFromRequest()
{
$fields = $this->prepareValidFields();
if (strpos(service('request')->getHeaderLine('Content-Type'), 'application/json') !== false)
{
$data = (array) service('request')->getJSON();
$data = array_intersect_key($data, array_fill_keys($fields, null));
}else{
$data = array_filter(service('request')->getPost($fields));
}
return new User($data);
}
Is this modification acceptable?
protected function buildUserFromRequest()
{
$fields = $this->prepareValidFields();
$data = array_filter(service('request')->getPost($fields));
if (empty($data)) {
//convert request body to associative array
$data = array_intersect_key(
json_decode(service('request')->getBody(), true),
array_fill_keys($fields, null)
);
}
return new User($data);
}
so it should be better!
I think that is likely fine. If you can submit a PR for it, that would be awesome.
Hi, no news about adding this issue to the release?
If someone wants to take this on as a PR please do.
I'll do
Maybe just like this?
protected function buildUserFromRequest()
{
$fields = $this->prepareValidFields();
// $data = array_filter(service('request')->getPost($fields));
// pulling data from $_REQUEST, get rid of NULL values
// works fine with both 'form-multipart' and 'application/json' content-types
// return type is array
$data = array_filter(service('request')->getVar($fields));
return new User($data);
}
And what about Shield? Shield's code is same as Myth.