我正在尝试使用护照通过社交名流为 Laravel API 实现 Facebook 登录:
api.php:
Route::middleware('api')->group(function () {
Route::group(['prefix' => 'auth'], function () {
Route::post('register', [RegisterController::class, 'register']);
Route::post('login', [LoginController::class, 'login']);
//Social Login
Route::get('login/google', [LoginController::class, 'redirectToGoogle']);
Route::get('login/google/callback', [LoginController::class, 'handleGoogleCallback']);
Route::get('login/facebook', [LoginController::class, 'redirectToFacebook']);
Route::get('login/facebook/callback', [LoginController::class, 'handleFacebookCallback']);
Route::group(['middleware' => 'auth:api'], function() {
});
});
});
LoginController.php:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
use App\Models\User;
use Laravel\Socialite\Facades\Socialite;
class LoginController extends Controller
{
public function login(Request $request)
{
$request->validate([
'email' => 'required|string|email',
'password' => 'required|string',
]);
if (Auth::attempt($request->only('email', 'password'))) {
return response()->json([
'token' => Auth::user()->createToken('UserApp')->accessToken,
]);
}
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}
protected function _registerOrLoginUser($data)
{
$user = User::where('email', $data->email)->first();
if (!$user) {
$user = new User();
$user->name = $data->name;
$user->email = $data->email;
$user->provider_id = $data->id;
$user->avatar = $data->avatar;
$user->save();
}
Auth::login($user);
}
protected function _registerOrLoginUserFacebook($data)
{
$user = User::where('facebook_id', $data->id)->first();
if (!$user) {
$user = new User();
$user->name = $data->name;
$user->email = $data->email;
$user->facebook_id = $data->id;
$user->save();
}
Auth::login($user);
}
// Google Login
public function redirectToGoogle()
{
return Socialite::driver('google')->stateless()->redirect();
}
public function handleGoogleCallback()
{
$user = Socialite::driver('google')->stateless()->user();
$this->_registerOrLoginUser($user);
$user = Auth::user();
$accessToken = $user->createToken('UserApp')->accessToken;
return response()->json([
'token' => $accessToken,
]);
}
// Facebook Login
public function redirectToFacebook()
{
// return Socialite::driver('facebook')->stateless()->redirect();
return Socialite::driver('facebook')->stateless()->redirect()->getTargetUrl();
}
public function handleFacebookCallback()
{
$user = Socialite::driver('facebook')->stateless()->user();
$this->_registerOrLoginUserFacebook($user);
$user = Auth::user();
$accessToken = $user->createToken('UserApp')->accessToken;
return response()->json([
'token' => $accessToken,
]);
}
}
服务.php:
'google' => [
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect' => env('GOOGLE_REDIRECT'),
],
'facebook' => [
'client_id' => env('FACEBOOK_CLIENT_ID'),
'client_secret' => env('FACEBOOK_CLIENT_SECRET'),
'redirect' => env('FACEBOOK_REDIRECT'),
],
.env:
GOOGLE_CLIENT_ID=Hidden
GOOGLE_CLIENT_SECRET=Hidden
GOOGLE_REDIRECT=http://127.0.0.1:8000/api/auth/login/google/callback
FACEBOOK_CLIENT_ID=Hidden
FACEBOOK_CLIENT_SECRET=Hidden
FACEBOOK_REDIRECT=http://127.0.0.1:8000/api/auth/login/facebook/callback
上面有两个登录功能,一个用于 Google,另一个用于 Facebook。
Google 登录工作正常,但我遇到 Facebook 登录问题。
当我转到“api/auth/login/facebook”时,我从 Facebook 得到这个:
在 Facebook 开发者仪表板中,我检查了 App ID 和 APP Secret,两者都是正确的。
Facebook 开发人员仪表板中的“有效 OAuth 重定向 URI”和“重定向 URI 以检查”字段也为空,因为自动允许本地主机:
那么问题出在哪里?
我发现现在,Facebook 登录应用程序似乎不再可能正确重定向到非 https 本地 uri,例如:
http://localhost/auth/facebook/callback
不过你有 2 个选择:
https://mydomain.test
这可以通过 Laravel Herd(使用:“herd secure”)、Laravel Valet(使用:“valet secure”)甚至 Laravel Sail(使用:“sail share”)等工具来实现。
为此,请从其站点安装 ngrok(它有免费版本)并运行以下命令:
php artisan serve
ngrok http 8000
然后您的终端将向您显示一个类似
https://xxxx-xx-xx-xxx-xx.ngrok-free.app
的 url,您可以在 .env 和 facebook 开发人员仪表板中使用它
我已经针对每个选项的整个过程编写了本指南: 使用 Socialite 通过 Facebook 登录您的 Laravel 应用程序(免责声明:这是我的网站)