Auth :: attempt在null上调用成员函数prepare()

时间:2019-07-10 14:34:16

标签: laravel-5

基本上,我得到一个用户名@company类型的用户,爆炸后,我搜索客户端特定数据库的连接数据。

在运行时更改数据库后,我尝试登录,但是Auth ::尝试不起作用。

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\SysClient;
use App\User;
use Config;
use Hash;
use DB;

...

public function authenticate(Request $request)
{
    $request->validate([
        'username' => 'required|string',
        'password' => 'required|string',
    ]);

    $data = explode('@', $request->username);
    $username = $data[0];
    $alias = $data[1];
    $password = $request->password;
    //$password = Hash::make($request->password);

    $client = SysClient::where('alias', $alias)->first();

    $connection = [
        "driver" => $client->driver,
        "host" => $client->host,
        "port" => $client->port,
        "database" => $client->database,
        "username" => $client->username,
        "password" => $client->password,
        "unix_socket" => $client->unix_socket,
        "charset" => $client->charset,
        "collation" => $client->collation,
        "prefix" => $client->prefix,
        "prefix_indexes" => $client->prefix_indexes,
        "strict" => $client->strict,
        "engine" => $client->engine
    ];

    $request->session()->put('current_database', $connection); // save $connection in session

    Config::set('database.connections.default', $connection); // set new connection
    DB::purge('default'); // purge connection settings
    DB::reconnect('default'); // reconnect database

    //dd(DB::connection()->getDatabaseName()); //it works!

    $credentials = [
        'username' => $username, // string
        'password' => $password, // string
        'active' => 1
    ];

    //dd(User::all()); //it works!

    //So far everything works, the error happens when executing the next line

    if (Auth::attempt($credentials)) {
        dd('Authentication passed...');
    } else {
        dd('fail');
    }

}

我希望Auth :: attempt返回true或false,但似乎不希望使用更新的数据库连接。

1 个答案:

答案 0 :(得分:0)

我找到了问题的根源,但我仍然不知道如何解决。

Google App Engine中的会话控制需要由数据库而不是文件来完成。

系统加载数据库“ main”,并将会话写入“ sessions”表。更改连接后,新数据库中不存在该会话,而laravel尝试修改/删除该会话的表记录时,找不到该记录并返回错误:

\ vendor \ laravel \ framework \ src \ Illuminate \ Database \ Connection.php中的“对成员函数prepare()的调用为null”

在线479:

$statement = $this->getPdo()->prepare($query);

将其放在上一行(478)

dd($query, $bindings);

我得到:

"update `sessions` set `payload` = ?, `last_activity` = ?, `user_id` = ?, `ip_address` = ?, `user_agent` = ? where `id` = ?"

array:6 [▼
  0 => "YTo0OntzOjY6Il90b2tlbiI7czo0MDoiNTVkSHFUS0tFeDF3SDhBeGRTN1E1UWJhblA2M3lhaGdueVNNSGFYRCI7czo5OiJfcHJldmlvdXMiO2E6MTp7czozOiJ1cmwiO3M6Mjc6Imh0dHA6Ly9sb2NhbGhvc3Q6 ▶"
  1 => 1562871843
  2 => null
  3 => "127.0.0.1"
  4 => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"
  5 => "OuxA1KMCkIPnobRHB626VlyivPFI6aW860CvEs7s"
]

我无法使用Google App Engine中文件的会话,它们需要保留在数据库中。然后,问题可能是如何将会话从数据库“主”中的表移动到客户端数据库中的表。或者,如果有可能在“主”数据库中结束会话并在客户端数据库中启动新会话。