使用 Laravel 5.2 的 Ajax 登录表单

问题描述 投票:0回答:5

我尝试使用 Laravel 5.2 Auth 创建带有 Ajax 的登录表单。

$(document).ready(function(){
$.ajaxSetup({
  headers: {
    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
  }
});

$('#login').on('click',function(e){
e.preventDefault(); 

var formData = {
    email: $('#email').val(),
    password: $('#password').val(),
}
    $.ajax({
        type: "POST",
        url: "/login",
        data: formData,
        success: function (data) {
           location.reload();
        },
        error: function (data) {

        }
    });

});

})enter code here

Laravel 默认登录函数:

public function login(Request $request)
{
$this->validateLogin($request);

// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
$throttles = $this->isUsingThrottlesLoginsTrait();

if ($throttles && $lockedOut = $this->hasTooManyLoginAttempts($request)) {
    $this->fireLockoutEvent($request);

    return $this->sendLockoutResponse($request);
}

$credentials = $this->getCredentials($request);

if (Auth::guard($this->getGuard())->attempt($credentials, $request->has('remember'))) {
    return $this->handleUserWasAuthenticated($request, $throttles);
}

// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
if ($throttles && ! $lockedOut) {
    $this->incrementLoginAttempts($request);
}

return $this->sendFailedLoginResponse($request);
}

/login 返回索引页面作为响应。 我需要关于错误消息或成功消息的 json 响应。 据说更改 Laravel 核心功能是不可取的。那我怎么才能得到呢?

php jquery ajax laravel laravel-5
5个回答
4
投票

据我了解,您的代码示例只是

AuthenticatesUser
特征的副本。

因此,为了避免大的变化并使其正常工作,只需将

app/Http/Controllers/LoginController.php
中的默认控制器代码替换为:

<?php

namespace App\Http\Controllers\Auth;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    public function __construct()
    {
        $this->middleware('guest', ['except' => 'logout']);
    }

    protected function username() {
        return 'email';
    }

    public function login(Request $request)
    {
        $credentials = $request->only($this->username(), 'password');
        $authSuccess = Auth::attempt($credentials, $request->has('remember'));

        if($authSuccess) {
            $request->session()->regenerate();
            return response(['success' => true], Response::HTTP_OK);
        }

        return
            response([
                'success' => false,
                'message' => 'Auth failed (or some other message)'
            ], Response::HTTP_FORBIDDEN);
    }

    public function logout(Request $request)
    {
        Auth::logout();
        $request->session()->flush();
        $request->session()->regenerate();

        return redirect('/');
    }
}



js部分可以保持不变:

$.ajax({
    type: "POST",
    url: "/login",
    data: formData,
    dataType:'json',
    success: function (response) {
       if(response.success) {
         window.location.replace('/dashboard');
       }
    },
    error: function (jqXHR) {
      var response = $.parseJSON(jqXHR.responseText);
      if(response.message) {
        alert(response.message);
      }
    }
});

但我个人更喜欢不处理提交的按钮,而是处理一般的表单,以防止在用户按下

enter
按钮时发生这种情况,而不是单击登录按钮。

检查这个例子:

html部分:

<form class="login" action="{{ url('/login') }}" method="post" data-type="json">
  <input type="text" name="email">
  <input type="password" name="password">
  <button type="submit">login</button>
</form>

js部分:

$(function() {

  $.ajaxSetup({
    headers: {
      'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
  });

  $('form.login:first').on('submit', function(e){
    e.preventDefault(); 
    
    var $this = $(this);

    $.ajax({
        type: $this.attr('method'),
        url: $this.attr('action'),
        data: $this.serializeArray(),
        dataType: $this.data('type'),
        success: function (response) {
           if(response.success) {
             location.reload();
           }
        },
        error: function (jqXHR) {
          var response = $.parseJSON(jqXHR.responseText);
          if(response.message) {
            alert(response.message);
          }
        }
    });
  });

});

1
投票

你可以试试加入jquery

dataType: 'JSON'

或尝试存储在会话中并使用

Redirect::back()

return redirect($this->loginPath())
       ->withInput($request->only('email', 'remember'))
       ->withErrors([
             'email' => $this->getFailedLoginMessage(),
        ]);

1
投票

请试试这个

use Validator;
use Auth;


public function postUserLogin(Request $request) {
    $credentials = array_trim($request->only('email', 'password'));
    $rules = ['email' => 'required|email|max:255',
        'password' => 'required'
    ];

    $validation = Validator::make($credentials, $rules);
    $errors = $validation->errors();
    $errors = json_decode($errors);
    if ($validation->passes()) {
        if (Auth::attempt(['email' => trim($request->email),
                    'password' => $request->password,
                        ], $request->has('remember'))) {


            return response()->json(['redirect' => true, 'success' => true], 200);
        } else {
            $message = 'Invalid username or password';

            return response()->json(['password' => $message], 422);
        }
    } else {
        return response()->json($errors, 422);
    }
}

0
投票

添加如下

  /**
     * Handle a login request to the application.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse
     *
     * @throws \Illuminate\Validation\ValidationException
     */
    public function login(Request $request)
    {
        $this->validateLogin($request);

        if ($this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);
            return response()->json( $this->sendLockoutResponse($request));
        }
        if ($this->attemptLogin($request)) {
            return response()->json( $this->sendLoginResponse($request) );
        }

        $this->incrementLoginAttempts($request);
        return response()->json($this->sendFailedLoginResponse($request));
    }

0
投票

在你的控制器中返回这样的响应 如果成功

return response()->json(['success' => 'Login successfully!']);
如果有任何错误
return response()->json(['success' => 'Login successfully!']);

并且在您的 .js 文件中,您必须应用这样的条件

function login(url) {

    event.preventDefault();
$.ajax({
      type: 'POST',
      url: url,
      data: $('#login-form').serialize(),
      success: function (response) {
  
      
        if (response.hasOwnProperty('errors')) {
          var loginErrorsMessage = response.errors;

          console.log(loginErrorsMessage); //your all errors 
       }
       if (response.hasOwnProperty('success')) {

          var successMessage = (response.success) 

         console.log(successMessage); //your message
          window.location.href = getBaseURL() + '/dashboard';
        }

});
}

您的登录表单将是这样的

 <form id="login-form" class="space-y-4 md:space-y-6">
  @csrf
      <div>
        <label for="email" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Your email</label>
        <input type="email" name="email" id="email" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="[email protected]" required="">
                                 
      </div>
      <div>
         <label for="password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Password</label>
          <input type="password" name="password" id="password" placeholder="••••••••" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" required="">
            
     </div>
     <button id="login_btn"  onclick="login('{{URL::to("custom-login")}}')"  class="w-full bg-indigo-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center text-white dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">Sign in</button>
      <p class="text-sm font-light text-gray-500 dark:text-gray-400">
                            Don’t have an account yet? <a href="{{url('register')}}" class="font-medium text-primary-600 hover:underline dark:text-primary-500">Sign up</a>
      </p>
 </form>
© www.soinside.com 2019 - 2024. All rights reserved.