Lae/app/Http/Controllers/Web/AuthController.php

287 lines
8.9 KiB
PHP
Raw Normal View History

2022-11-06 11:28:22 +00:00
<?php
namespace App\Http\Controllers\Web;
2022-11-06 11:28:22 +00:00
use App\Http\Controllers\Controller;
2023-03-06 11:03:20 +00:00
use App\Models\User;
2023-01-17 17:29:00 +00:00
use App\Notifications\User\UserNotification;
2023-03-11 06:21:21 +00:00
use Exception;
2023-02-22 13:32:33 +00:00
use Illuminate\Http\JsonResponse;
2023-01-10 13:42:27 +00:00
use Illuminate\Http\RedirectResponse;
2022-11-06 11:28:22 +00:00
use Illuminate\Http\Request;
2023-02-07 09:45:31 +00:00
use Illuminate\Support\Carbon;
2022-11-06 11:28:22 +00:00
use Illuminate\Support\Facades\Auth;
2023-02-02 05:51:32 +00:00
use Illuminate\Support\Facades\Cache;
2023-03-11 06:21:21 +00:00
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
2023-01-10 13:42:27 +00:00
use Illuminate\View\View;
2023-03-11 06:21:21 +00:00
use function back;
use function config;
use function redirect;
use function session;
use function view;
2022-11-06 11:28:22 +00:00
class AuthController extends Controller
{
2023-01-10 13:42:27 +00:00
public function index(Request $request): View|RedirectResponse
2022-11-06 11:28:22 +00:00
{
// if logged in
2023-01-14 21:37:25 +00:00
if ($request->filled('callback')) {
$callback = $request->input('callback');
2022-11-06 11:28:22 +00:00
2023-01-14 21:37:25 +00:00
session(['callback' => $callback]);
2023-02-17 12:21:20 +00:00
if ($request->user('web')) {
2023-01-14 21:37:25 +00:00
$callbackHost = parse_url($callback, PHP_URL_HOST);
$dashboardHost = parse_url(config('settings.dashboard.base_url'), PHP_URL_HOST);
if ($callbackHost === $dashboardHost) {
2023-03-11 06:21:21 +00:00
if (!$request->user('web')->isRealNamed()) {
2023-01-15 00:32:50 +00:00
return redirect()->route('real_name.create')->with('status', '重定向已被打断,需要先实人认证。');
}
2023-02-17 13:18:58 +00:00
$token = $request->user()->createToken('Dashboard')->plainTextToken;
2023-01-14 21:37:25 +00:00
2023-03-11 06:21:21 +00:00
return redirect($callback . '?token=' . $token);
2023-01-14 21:37:25 +00:00
}
2022-11-06 11:28:22 +00:00
2023-02-17 13:18:58 +00:00
session(['referer.domain' => parse_url($request->header('referer'), PHP_URL_HOST)]);
2022-11-28 15:58:39 +00:00
return redirect()->route('confirm_redirect');
2022-11-06 11:28:22 +00:00
} else {
2023-02-08 07:07:24 +00:00
// url.intended 存放当前页面 URL
session(['url.intended' => $request->fullUrl()]);
return redirect()->route('login')->with('status', '要继续,请先登录账号。');
2022-11-06 11:28:22 +00:00
}
}
2023-02-26 13:10:57 +00:00
return $request->user('web') ? view('index') : view('auth.login');
2022-11-06 11:28:22 +00:00
}
2023-01-10 13:42:27 +00:00
public function confirm_redirect(Request $request): View
2022-11-28 15:58:39 +00:00
{
$callback = $request->callback ?? session('callback');
2023-02-17 13:18:58 +00:00
$referer_host = session('referer.domain');
return view('confirm_redirect', compact('callback', 'referer_host'));
2022-11-28 15:58:39 +00:00
}
2023-02-22 13:32:33 +00:00
public function update(Request $request): RedirectResponse|JsonResponse
2023-02-02 04:55:48 +00:00
{
$request->validate([
2023-02-22 13:32:33 +00:00
'name' => 'nullable|sometimes|string|max:255',
'receive_marketing_email' => 'nullable|sometimes|boolean',
2023-02-02 04:55:48 +00:00
]);
$user = $request->user('web');
2023-02-22 13:32:33 +00:00
$user->update($request->only('name', 'receive_marketing_email'));
if ($request->ajax()) {
return $this->success($user->only('name', 'receive_marketing_email'));
}
2023-02-02 04:55:48 +00:00
return back()->with('success', '更新成功。');
}
2023-01-10 13:42:27 +00:00
public function newToken(Request $request): RedirectResponse
2022-11-06 11:28:22 +00:00
{
$request->validate([
2023-02-02 12:58:31 +00:00
'name' => 'required|string|max:255',
2022-11-06 11:28:22 +00:00
]);
$token = $request->user()->createToken(
$request->input('name'),
);
2022-11-06 11:28:22 +00:00
return back()->with('token', $token->plainTextToken);
}
2023-01-10 13:42:27 +00:00
public function deleteAll(Request $request): RedirectResponse
2022-11-06 11:28:22 +00:00
{
2023-01-17 17:29:00 +00:00
$user = $request->user('web');
$user->tokens()->delete();
$user->notify(new UserNotification('莱云', '您的所有 Token 已被删除。'));
2022-11-06 11:28:22 +00:00
return back()->with('success', '所有 Token 删除成功。');
}
2023-01-10 13:42:27 +00:00
public function logout(): RedirectResponse
2022-11-06 11:28:22 +00:00
{
Auth::guard('web')->logout();
session()->regenerateToken();
return redirect()->route('index');
}
2023-02-02 05:51:32 +00:00
2023-02-02 11:18:16 +00:00
public function exitSudo(): RedirectResponse
{
session()->forget('auth.password_confirmed_at');
2023-02-02 12:46:22 +00:00
return back();
2023-02-02 11:18:16 +00:00
}
2023-02-02 05:51:32 +00:00
public function showAuthRequest($token): View|RedirectResponse
{
2023-03-11 06:21:21 +00:00
$data = Cache::get('auth_request:' . $token);
2023-02-02 05:51:32 +00:00
if (empty($data)) {
return redirect()->route('index')->with('error', '登录请求的 Token 不存在或已过期。');
}
if (isset($data['user'])) {
return redirect()->route('index')->with('error', '登录请求的 Token 已被使用。');
}
2023-02-02 06:08:25 +00:00
// 登录后跳转的地址
session(['url.intended' => route('auth_request.show', $token)]);
2023-02-02 05:51:32 +00:00
return view('auth.request', [
'data' => $data,
]);
}
2023-02-26 08:41:44 +00:00
public function storeAuthRequest(Request $request): RedirectResponse|View
2023-02-02 05:51:32 +00:00
{
$request->validate([
'token' => 'required|string|max:128',
]);
2023-03-11 06:21:21 +00:00
$data = Cache::get('auth_request:' . $request->input('token'));
2023-02-02 05:51:32 +00:00
if (empty($data)) {
return back()->with('error', '登录请求的 Token 不存在或已过期。');
}
if (isset($data['user'])) {
return back()->with('error', '登录请求的 Token 已被使用。');
}
2023-02-07 09:45:31 +00:00
$user = $request->user('web');
$data['user'] = $user->getOnlyPublic([], [
'email',
'email_verified_at',
'real_name_verified_at',
]);
$abilities = $data['meta']['abilities'] ?? ['*'];
2023-02-07 09:45:31 +00:00
if (isset($data['meta']['require_token']) && $data['meta']['require_token']) {
$data['token'] = $user->createToken($data['meta']['description'] ?? Carbon::now()->toDateString(), $abilities)->plainTextToken;
2023-02-07 09:45:31 +00:00
}
2023-02-02 05:51:32 +00:00
2023-03-11 06:21:21 +00:00
Cache::put('auth_request:' . $request->input('token'), $data, 60);
2023-02-02 05:51:32 +00:00
2023-02-26 08:41:44 +00:00
if (isset($data['meta']['return_url']) && $data['meta']['return_url']) {
2023-03-11 06:21:21 +00:00
return redirect()->to($data['meta']['return_url'] . '?auth_request=' . $request->input('token'));
2023-02-26 08:41:44 +00:00
}
2023-02-02 05:51:32 +00:00
return redirect()->route('index')->with('success', '登录请求已确认。');
}
2023-03-06 11:03:20 +00:00
public function fastLogin(string $token): RedirectResponse
{
2023-03-11 06:21:21 +00:00
$cache_key = 'session_login:' . $token;
$user_id = Cache::get('session_login:' . $token);
2023-03-06 11:03:20 +00:00
if (empty($user_id)) {
return redirect()->route('index')->with('error', '登录请求的 Token 不存在或已过期。');
}
$user = User::find($user_id);
if (empty($user)) {
return redirect()->route('index')->with('error', '无法验证。');
}
Auth::guard('web')->login($user);
Cache::forget($cache_key);
return redirect()->route('index');
}
2023-03-11 06:21:21 +00:00
public function redirect(Request $request)
{
$request->session()->put('state', $state = Str::random(40));
$query = http_build_query([
'client_id' => config('oauth.client_id'),
'redirect_uri' => config('oauth.callback_uri'),
'response_type' => 'code',
'scope' => config('oauth.scope'),
'state' => $state,
]);
return redirect()->to(config('oauth.oauth_auth_url') . '?' . $query);
}
public function callback(Request $request)
{
try {
$authorize = Http::asForm()->throw()->post(config('oauth.oauth_token_url'), [
'grant_type' => 'authorization_code',
'client_id' => config('oauth.client_id'),
'client_secret' => config('oauth.client_secret'),
'redirect_uri' => config('oauth.callback_uri'),
'code' => $request->input('code'),
])->getBody();
} catch (Exception $e) {
return redirect()->route('index')->with('error', '无法获取授权。' . $e->getMessage());
}
$authorize = json_decode($authorize);
$http = Http::asForm()->withHeaders([
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $authorize->access_token
])->throw();
$oauth_user = $http->get(config('oauth.oauth_user_url'))->object();
$real_name = $http->get(config('oauth.oauth_real_name_url'))->object();
$user_sql = User::where('email', $oauth_user->email);
$user = $user_sql->first();
if (is_null($user)) {
$name = $oauth_user->name;
$email = $oauth_user->email;
$email_verified_at = $oauth_user->email_verified_at;
$user = new User();
$user->name = $name;
$user->email = $email;
$user->email_verified_at = $email_verified_at;
$user->real_name_verified_at = $real_name->real_name_verified_at;
$user->real_name = $real_name->real_name;
$user->id_card = $real_name->id_card;
$user->password = Hash::make(Str::random(16));
$user->save();
$request->session()->put('auth.password_confirmed_at', time());
} else {
if ($user->name != $oauth_user->name) {
User::where('email', $oauth_user->email)->update([
'name' => $oauth_user->name
]);
}
}
Auth::guard('web')->loginUsingId($user->id, true);
return redirect()->route('index');
}
2022-11-06 11:28:22 +00:00
}