向Laravel中的本机身份验证添加附加数据(ajax)

向Laravel中的本机身份验证添加附加数据(ajax),ajax,laravel,Ajax,Laravel,我试图通过在用户登录后编写统计数据来在Laravel中实现用户跟踪。即位置、时区等。我有点幸运地实现了它 我通过在登录表单上附加事件侦听器提交按钮来使用ajax。提交表单后,将调用ajax方法。此方法通过使用api调用获取用户的统计信息。然后,ajax请求将该数据发送到StatsController@store,然后将该条目记录到统计表中 这只能通过使用e.preventDefault()来实现,如果我不使用它,记录不会插入到数据库中,它会抛出一个错误,在重定向到仪表板后很快消失 Ajax方法驻

我试图通过在用户登录后编写统计数据来在Laravel中实现用户跟踪。即位置、时区等。我有点幸运地实现了它

我通过在登录表单上附加事件侦听器提交按钮来使用ajax。提交表单后,将调用ajax方法。此方法通过使用api调用获取用户的统计信息。然后,ajax请求将该数据发送到
StatsController@store
,然后将该条目记录到统计表中

这只能通过使用
e.preventDefault()来实现,如果我不使用它,记录不会插入到数据库中,它会抛出一个错误,在重定向到仪表板后很快消失

Ajax方法驻留在js文件中,该文件在布局文件中被调用

下面是一个ajax方法:

function getCoords(){

    return fetch('https://ipinfo.io/geo')
    .then((response) => {
        if (!response.ok) {
            throw new Error('Network response was not ok');
        }
        else{

            return response.json();

        }

    })
    .then((response) => {

        let url = "/writeStats";
        let token = document.querySelector("meta[name='csrf-token']").getAttribute("content");
        let forma = document.getElementById("loginForm");

        let formElements = {};

        formElements.email = forma.elements[1].value;
        formElements.password = forma.elements[2].value;

        $.ajax({
            url: url,
            type: 'POST',
            data: {_token: token , message: "bravo", stats: response, formElements: formElements},
            dataType: 'JSON',
            success: (response) => { 
                console.log("success");
                console.log(response);
            },
            error: (response) => {
                console.log("error");
                console.log(response);
            }
        }); 

    })
    .catch((error) => {
        console.error('There has been a problem with your fetch operation:', error);
    });

}

window.addEventListener("click", (e) => {

    if(e.target.id==="loginBtn"){
        //e.preventDefault();
        getCoords();
    }

});
web.php:

Route::post('/writeStats','StatsController@store');
StatsController:

public function store(Request $request)
{
    if($request->ajax()){

        $email = $request->formElements["email"];
        $password = $request->formElements["password"];

        $user = DB::table('users')->where("email", "=", $email)->first();

        if(Hash::check($password, $user->password)) {   

            $stat = new Stats;
            $stat->ip = $request->stats["ip"];
            $stat->city = $request->stats["city"];
            $stat->region = $request->stats["region"];
            $stat->country = $request->stats["country"];
            $stat->coords = $request->stats["loc"];
            $stat->timezone = $request->stats["timezone"];
            $stat->user_id = $user->id;
            $stat->save();

            $response = array(
                "message" => "bravo",
                "request" => $request->all(),
                "stats" => $request->stats,
                "user" => $user,
                "stat" => $stat,
            );

            return response()->json($response);

        }

    }

}
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

use Illuminate\Http\Request;
use Auth;
use App\Stats;

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = '/dashboard';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    public function authenticated(Request $request)
    {

        $email = $request->formElements["email"];
        $password = $request->formElements["password"];

        if (Auth::attempt(['email' => $email,'password' => $password])) {

            $stat = new Stats;
            $stat->ip = $request->stats["ip"];
            $stat->city = $request->stats["city"];
            $stat->region = $request->stats["region"];
            $stat->country = $request->stats["country"];
            $stat->coords = $request->stats["loc"];
            $stat->timezone = $request->stats["timezone"];
            $stat->user_id = auth()->user()->id;
            $stat->save();

            $response = array(
                "stat" => $request->all(),
            );

            return redirect()->intended('dashboard');
        }
    }
}
php artisan--version
显示了
Laravel Framework 6.9.0

我的问题是:如何在用户登录之后插入stats表

Edit1:

我现在正在尝试一些不同的方法。我现在使用LoginController中的
authenticated
方法,而不是StatController中的一些自定义方法

public function authenticated(Request $request)
    {
        $credentials = $request->only('email', 'password');

        $email = $request->input("email");
        $password = $request->input("password");

        $user = DB::table('users')->where("email", "=", $email)->first();
        if (Auth::attempt($credentials)) {

            $stat = new Stats;
            $stat->ip = $request->stats["ip"];
            $stat->city = $request->stats["city"];
            $stat->region = $request->stats["region"];
            $stat->country = $request->stats["country"];
            $stat->coords = $request->stats["loc"];
            $stat->timezone = $request->stats["timezone"];
            $stat->user_id = auth()->user()->id;
            $stat->save();

            $response = array(
                "stat" => $request->all(),
            );

            return redirect()->intended('dashboard');

        }
    }
在web.php中:

Route::post('/login','Auth\LoginController@authenticated');
还是不走运。我只是不知道该用什么方法。感觉如此接近,就像我错过了一些小东西

Edit2:

让我重新表述一下问题:

如何向登录控制器发送api调用响应,以便在对用户进行身份验证后,我可以将api响应数据插入另一个表(不是用户表)? 我可以:

  • 以某种方式将api响应插入到身份验证请求中
  • 或者,如何在将记录同时写入表
    stats
    时进行身份验证

  • 我尝试了两种方法(见:原创和编辑),但不确定我应该写什么

    这是它的预期行为。因为在您的用例中表单提交依赖于异步操作,所以您需要这种行为

    事件接口的preventDefault()方法告诉用户代理,如果事件没有得到显式处理,则不应像通常那样执行其默认操作


    更新:Ref:用于嵌套异步操作。

    我找到了一个非常有效的解决方案。为了更好地解释,我有几个错误:

    第一个是ajax调用中的
    dataType
    ,其中预期将返回json响应。不需要任何响应,因为在登录和随后从api插入数据时,用户将被发送到
    /dashboard

    第二个是我使用的
    e.preventDefault()因为我想看看在提交的情况下我会得到什么。没有必要这样解释,前一段的最后一句话

    顺便说一句,返回的是html代码,因为用户被重定向到查看

    以下是修订后的代码:

    登录控制器:

    public function store(Request $request)
    {
        if($request->ajax()){
    
            $email = $request->formElements["email"];
            $password = $request->formElements["password"];
    
            $user = DB::table('users')->where("email", "=", $email)->first();
    
            if(Hash::check($password, $user->password)) {   
    
                $stat = new Stats;
                $stat->ip = $request->stats["ip"];
                $stat->city = $request->stats["city"];
                $stat->region = $request->stats["region"];
                $stat->country = $request->stats["country"];
                $stat->coords = $request->stats["loc"];
                $stat->timezone = $request->stats["timezone"];
                $stat->user_id = $user->id;
                $stat->save();
    
                $response = array(
                    "message" => "bravo",
                    "request" => $request->all(),
                    "stats" => $request->stats,
                    "user" => $user,
                    "stat" => $stat,
                );
    
                return response()->json($response);
    
            }
    
        }
    
    }
    
    <?php
    
    namespace App\Http\Controllers\Auth;
    
    use App\Http\Controllers\Controller;
    use Illuminate\Foundation\Auth\AuthenticatesUsers;
    
    use Illuminate\Http\Request;
    use Auth;
    use App\Stats;
    
    class LoginController extends Controller
    {
        /*
        |--------------------------------------------------------------------------
        | Login Controller
        |--------------------------------------------------------------------------
        |
        | This controller handles authenticating users for the application and
        | redirecting them to your home screen. The controller uses a trait
        | to conveniently provide its functionality to your applications.
        |
        */
    
        use AuthenticatesUsers;
    
        /**
         * Where to redirect users after login.
         *
         * @var string
         */
        protected $redirectTo = '/dashboard';
    
        /**
         * Create a new controller instance.
         *
         * @return void
         */
        public function __construct()
        {
            $this->middleware('guest')->except('logout');
        }
    
        public function authenticated(Request $request)
        {
    
            $email = $request->formElements["email"];
            $password = $request->formElements["password"];
    
            if (Auth::attempt(['email' => $email,'password' => $password])) {
    
                $stat = new Stats;
                $stat->ip = $request->stats["ip"];
                $stat->city = $request->stats["city"];
                $stat->region = $request->stats["region"];
                $stat->country = $request->stats["country"];
                $stat->coords = $request->stats["loc"];
                $stat->timezone = $request->stats["timezone"];
                $stat->user_id = auth()->user()->id;
                $stat->save();
    
                $response = array(
                    "stat" => $request->all(),
                );
    
                return redirect()->intended('dashboard');
            }
        }
    }
    

    因此,如果您想在Laravel中的身份验证过程中添加ajax调用,,那么对于“关注的人”来说,这就是一个解决方案。可能还可以用来做其他事情。。。比如自定义身份验证之类的

    是的,我知道。我不知道的是如何首先提交从api派生的数据,然后继续进行身份验证和随后的重定向。如何实现这一点?身份验证是本地Laravel身份验证,而不是来自ajax调用。您可以在控制器方法中看到这一点。所以我不需要连锁反应。我需要将api的响应“注入”到本机Laravel身份验证请求。因此,您希望提交本机表单,但在该事件之前进行异步调用?简而言之,是的。我想检查(本机)身份验证,同时获取api调用响应并将其插入到表“stats”中。您是否尝试在异步完成后提交表单?form.submit()-您仍然需要使用preventDefault()