Laravel 5.3 Ajax Login

此生再无相见时 提交于 2019-12-10 17:33:58

问题


I'm trying to login my users with ajax with a new Laravel 5.3 project.

I've generated the auth routes, which got added to my web.php:

Auth::routes();

I have a html form with email, and password inputs and the csrf field. Then I also have this javascript file:

$("form.login").submit(function(e) {
    e.preventDefault();

    $.ajax({   
        method: "POST",
        dataType: "json",
        headers: { 
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
        },
        data: $("form.login").serialize(),
        url: "/login"
    })
    .done(function(data) {
        console.log(data);
    });
});

When I post it however, this shows up in my network tab:

It redirects back to the original page, without returning any data.

Why is it doing this? Does 5.3 not give json responses anymore?


回答1:


The Complete Solution:

Hi reinierkors,

I also tried to do the same with the 5.3 version, I finally solved it :) and the solution is very clean.

First, I created a new folder under App\Http\Controllers\Api called Auth, I did it just to add new auth controllers for the api so I can rewrite some functions, then I copied the auth controllers (LoginController, ForgotPasswordController, RegisterController) to this new folder.

In LoginController Class: I rewrited the functions that were making the redirects.

The first function: will be automatically called when the authentication return success.

The second function: will be automatically called when the authentication return error.

The last function: will be automatically called when the user has been locked out after trying 5 login attempts.

     /**
     * Send the response after the user was authenticated.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    protected function sendLoginResponse(Request $request) {
        $this->clearLoginAttempts($request);

        return response()->json(['SUCCESS' => 'AUTHENTICATED'], 200);
    }

    /**
     * Get the failed login response instance.
     *
     * @return \Illuminate\Http\Response
     */
    protected function sendFailedLoginResponse() {
        return response()->json(['ERROR' => 'AUTH_FAILED'], 401);
    }

    /**
     * Error after determining they are locked out.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    protected function sendLockoutResponse(Request $request) {
        $seconds = $this->limiter()->availableIn(
            $this->throttleKey($request)
        );

        return response()->json(['ERROR' => 'TOO_MANY_ATTEMPTS', 'WAIT' => $seconds], 401);
    }

In RegisterController Class: I rewrited the functions that were making the redirects.

In the first function: I modified the validator response to return a more comfortable response (array) to work with.

The second function: will be automatically called when the registration return success.

    /**
     * Handle a registration request for the application.
     *
     * @param Request $request
     * @return \Illuminate\Http\Response
     */
    public function register(Request $request) {
        $validator = $this->validator($request->all());

        if($validator->fails())
            return response()->json(['ERROR' => $validator->errors()->getMessages()], 422);

        event(new Registered($user = $this->create($request->all())));

        $this->guard()->login($user);

        return $this->registered($request, $user)
            ?: redirect($this->redirectPath());
    }

    /**
     * The user has been registered.
     *
     * @param Request $request
     * @param  mixed $user
     * @return mixed
     */
    protected function registered(Request $request, $user) {
        return response()->json(['SUCCESS' => 'AUTHENTICATED']);
    }

In ForgotPasswordController Class: I rewrited the function that was making the redirects.

I modified the reset link email function so we can get the messages and display as json instead of the redirects.

     /**
     * Send a reset link to the given user.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function sendResetLinkEmail(Request $request)
    {
        $validator = Validator::make($request->only('email'), [
            'email' => 'required|email',
        ]);

        if ($validator->fails())
            return response()->json(['ERROR' => 'VALID_EMAIL_REQUIRED'], 422);

        // We will send the password reset link to this user. Once we have attempted
        // to send the link, we will examine the response then see the message we
        // need to show to the user. Finally, we'll send out a proper response.
        $response = $this->broker()->sendResetLink(
            $request->only('email')
        );

        if ($response === Password::RESET_LINK_SENT) {
            return response()->json(['SUCCESS' => 'EMAIL_SENT'], 200);
        }

        // If an error was returned by the password broker, we will get this message
        // translated so we can notify a user of the problem. We'll redirect back
        // to where the users came from so they can attempt this process again.
        return response()->json(['ERROR' => 'EMAIL_NOT_FOUND'], 401);
    }



回答2:


For explanation about my mistake (the kind of same as op), see the edit history of this post.

How I solved it

with a little bit of help from @iSensical

Inside the app/Exceptions/Handler.php there is a unauthenticated function which, by default, knows if the request expects a json answer with the expectsJson() function.

The problem didn't came from Laravel by itself. It was, surprisingly, the human factor. I wrote a bad piece of code.

My ajax request did not used an intuitive header for Laravel.

I had this:

$http({
    url     : '{{ route('angular.auth.login.post') }}',
    method  : 'POST',
    data    : $.param($scope.user)+'&x-csrf-token='+CSRF_TOKEN,
    headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
})
[...]

We might have used a bad Content-Type. The correct one was application/json like this:

headers : { 'Content-Type': 'application/json' }


来源:https://stackoverflow.com/questions/39675978/laravel-5-3-ajax-login

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!