admin管理员组

文章数量:1123509

I am trying to create a login page in PHP Luminova, but doesn't work well with Ajax requests.

How can i update my login class to work with Ajax and redirect to another page after a successful login or show an error message?

The current example doesn't work.

The problem am facing is when i log in, the Ajax doesn't redirect on successful login nor update the error message to the `loginMessage` element.

Also when I check the browser network request tab, while logging in, when an error is encountered, the message shows in the browser preview while the element I added to show the error only shows `undefined`. Same as when login is successful the dashboard is shown in the preview, but if I reload the page after login, it will take me to the dashboard.

Please, i will appreciate any help, i want to show an error message when an error happens and redirect to the dashboard when successful

My login controller class.

use Luminova\Base\BaseController;
use Luminova\Attributes\Prefix;
use Luminova\Attributes\Route;
use Luminova\Security\Crypter;
use App\Models\User;

#[Prefix(pattern: '/api/(:root)', onError: [ViewErrors::class, 'onApiError'])]
class UserController extends BaseController
{
    #[Route('/api/login', methods: ['POST'])]
    public function userLogin(): int 
    {
        if ($this->request->getBody() === []) {
            echo 'Invalid request body';
            return STATUS_ERROR;
        }elseif($this->app->session->online()){
            echo "You are already logged in";
           return $this->view('dashboard');
        }

        $this->validate->rules = [
            'email' => 'required|email',
            'password' => 'required|min(6)',
        ];

        $this->validate->errors = [
            'email' => [
                'required' => 'Email must not be empty',
                'email' => 'Email address must be a valid email.'
            ],
            'password' => [
                'required' => 'Password must not be empty',
                'min' => 'Password must not be less than 6 characters'
            ],
        ];

        if(!$this->validate->validate($this->request->getBody())){
            echo $this->validate->getError();
            return STATUS_ERROR;
        }else{

            $password = $this->request->getPost("password");
            $email = escape($this->request->getPost("email"));
            $user = (new User())->findByEmail($email);
        
            if(!$user){
                echo 'Not matching email found.';
                return STATUS_ERROR;
            }elseif(Crypter::verify($password, $user->user_password_hash)){
                $this->app->session->set('name', $user->name);
                $this->app->session->set('email', $user->email);
                $this->app->session->set('id', $user->id);
                $this->app->session->synchronize(ip_address());

                return $this->view('dashboard');
            }
        }

        echo 'Invalid email or password provided';
        return STATUS_ERROR;
    }
}

Here is my javascript login.

$('#loginAccountForm').on('submit', function (e) {
    e.preventDefault();
    $.ajax({
        url: '<?php echo href(/api/login);?>',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({
            username: $('#username').val(),
            password: $('#password').val(),
        }),
        success: function (response) {
            if (response.success) {
                window.location.href = '/dashboard';
            } else {
                $('#loginMessage').html('<p style="color: red;">' + response.message + '</p>');
            }
        }
    });
});

I am trying to create a login page in PHP Luminova, but doesn't work well with Ajax requests.

How can i update my login class to work with Ajax and redirect to another page after a successful login or show an error message?

The current example doesn't work.

The problem am facing is when i log in, the Ajax doesn't redirect on successful login nor update the error message to the `loginMessage` element.

Also when I check the browser network request tab, while logging in, when an error is encountered, the message shows in the browser preview while the element I added to show the error only shows `undefined`. Same as when login is successful the dashboard is shown in the preview, but if I reload the page after login, it will take me to the dashboard.

Please, i will appreciate any help, i want to show an error message when an error happens and redirect to the dashboard when successful

My login controller class.

use Luminova\Base\BaseController;
use Luminova\Attributes\Prefix;
use Luminova\Attributes\Route;
use Luminova\Security\Crypter;
use App\Models\User;

#[Prefix(pattern: '/api/(:root)', onError: [ViewErrors::class, 'onApiError'])]
class UserController extends BaseController
{
    #[Route('/api/login', methods: ['POST'])]
    public function userLogin(): int 
    {
        if ($this->request->getBody() === []) {
            echo 'Invalid request body';
            return STATUS_ERROR;
        }elseif($this->app->session->online()){
            echo "You are already logged in";
           return $this->view('dashboard');
        }

        $this->validate->rules = [
            'email' => 'required|email',
            'password' => 'required|min(6)',
        ];

        $this->validate->errors = [
            'email' => [
                'required' => 'Email must not be empty',
                'email' => 'Email address must be a valid email.'
            ],
            'password' => [
                'required' => 'Password must not be empty',
                'min' => 'Password must not be less than 6 characters'
            ],
        ];

        if(!$this->validate->validate($this->request->getBody())){
            echo $this->validate->getError();
            return STATUS_ERROR;
        }else{

            $password = $this->request->getPost("password");
            $email = escape($this->request->getPost("email"));
            $user = (new User())->findByEmail($email);
        
            if(!$user){
                echo 'Not matching email found.';
                return STATUS_ERROR;
            }elseif(Crypter::verify($password, $user->user_password_hash)){
                $this->app->session->set('name', $user->name);
                $this->app->session->set('email', $user->email);
                $this->app->session->set('id', $user->id);
                $this->app->session->synchronize(ip_address());

                return $this->view('dashboard');
            }
        }

        echo 'Invalid email or password provided';
        return STATUS_ERROR;
    }
}

Here is my javascript login.

$('#loginAccountForm').on('submit', function (e) {
    e.preventDefault();
    $.ajax({
        url: '<?php echo href(/api/login);?>',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({
            username: $('#username').val(),
            password: $('#password').val(),
        }),
        success: function (response) {
            if (response.success) {
                window.location.href = '/dashboard';
            } else {
                $('#loginMessage').html('<p style="color: red;">' + response.message + '</p>');
            }
        }
    });
});
Share Improve this question edited 15 hours ago Peter 1,9042 gold badges21 silver badges52 bronze badges asked 17 hours ago sotfysotfy 231 silver badge5 bronze badges New contributor sotfy is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 6
  • 1 In the cases of success your PHP returns return $this->view('dashboard'); - which will presumably generate some HTML and return that content to the AJAX request. But the AJAX code clearly expects a parseable JSON response (because if (response.success) is evidently expecting to process an object with a success property). But a) your PHP returns HTML, not JSON, and b) even if PHP returned JSON your AJAX's callback code doesn't try to parse the JSON into a JS object before using it. So both those steps are missing. – ADyson Commented 17 hours ago
  • 1 And in the error case, your PHP just echoes some plain text - again this is not JSON. Your PHP code seems to be set up to receive a regular postback rather than an AJAX request. The PHP code needs modifiying to output what the AJAX code is expecting it to. – ADyson Commented 17 hours ago
  • So it's not really clear where you're stuck - it's self-evident at a moment's glance that the AJAX and PHP code don't align in terms of the PHP's output and the AJAX code's expectations - have you tried to do anything about it so far? Where precisely do you need our help? Are you familiar with how to make PHP output JSON, using json_encode(), for example? – ADyson Commented 17 hours ago
  • @ADyson yes i need help, i don't know how to make it output JSON. I will appreciate if you help out. – sotfy Commented 17 hours ago
  • 1 If not, maybe consider referring to your framework's documentation on providing appropriate content type responses - I think you probably start reading here: luminova.ng/docs/3.0.2/templates/response – ADyson Commented 16 hours ago
 |  Show 1 more comment

1 Answer 1

Reset to default 2

Based on documentation here https://luminova.ng/docs/3.0.2/templates/response as @ADyson suggested. Update your controller login method to output json response following your ajax implementation. Use the response function instead of directly echoing the response.

Below is an optimized example of how your method should look.

use Luminova\Base\BaseController;
use Luminova\Attributes\Prefix;
use Luminova\Attributes\Route;
use Luminova\Security\Crypter;
use App\Models\User;

#[Prefix(pattern: '/api/(:root)', onError: [ViewErrors::class, 'onApiError'])]
class UserController extends BaseController
{
    #[Route('/api/login', methods: ['POST'])]
    public function userLogin(): int 
    {
        if ($this->request->getBody() === []) {
            return response()->json(['success' => false, 'message' => 'Invalid request body.']);
        }

        if($this->app->session->online()){
            return response()->json(['success' => true, 'message' => 'You are already logged in.']);
        }

        $this->validate->rules = [
            'email' => 'required|email',
            'password' => 'required|min(6)',
        ];

        $this->validate->errors = [
            'email' => [
                'required' => 'Email must not be empty',
                'email' => 'Email address must be a valid email.'
            ],
            'password' => [
                'required' => 'Password must not be empty',
                'min' => 'Password must not be less than 6 characters'
            ],
        ];

        if(!$this->validate->validate($this->request->getBody())){
            return response()->json(['success' => false, 'message' => $this->validate->getError()]);
        }

        $password = $this->request->getPost("password");
        $email = escape($this->request->getPost("email"));
        $user = (new User())->findByEmail($email);
    
        if(!$user){
            return response()->json(['success' => false, 'message' => 'Not matching email found.']);
        }

        if(Crypter::verify($password, $user->user_password_hash)){
            $this->app->session->set('name', $user->name);
            $this->app->session->set('email', $user->email);
            $this->app->session->set('id', $user->id);
            $this->app->session->synchronize(ip_address());

            return response()->json(['success' => true, 'message' => 'Login successful.']);
        }

        return response()->json(['success' => false, 'message' => 'Invalid email or password provided.']);
    }
}

本文标签: How to Make PHP Luminova login work with jQuery AjaxStack Overflow