Вход пользователя в Laravel для продвижения веб-приложения с помощью вызова API - PullRequest
0 голосов
/ 17 декабря 2018

Я настроил паспортные маршруты для входа пользователей через API для мобильного приложения.Однако часть мобильного приложения использует веб-просмотр для отображения стробированного контента, а часть его извлекает из API для другого контента.

Как только пользователь входит в приложение с помощью API, мне нужно, чтобы они также были зарегистрированыв веб-контент в то же время.

Однако с помощью API не создано ни одного сеанса.Как я могу одновременно входить и выходить из системы через API таким образом, чтобы при отображении веб-просмотра он переносился?

Я пытался использовать это на моем API\LoginController.php для входа в систему:

protected function sendLoginResponse(Request $request)
{
    if ($request->hasSession()) {
        $request->session()->regenerate();
    } else {
        // Login user for PWA pages.
        \Session::start();
        \Auth::login($this->guard()->user());
    }
    $this->clearLoginAttempts($request);
    return $this->authenticated($request, $this->guard()->user());
}

protected function authenticated(Request $request, User $user): ?JsonResponse
{
    return response()->json(['token' => $user->createToken(config('app.name'))->accessToken], 200);
}

Это расширяет базовое значение по умолчанию Laravel LoginController.php, но переопределяет эти методы для поддержки ответов JSON.

Связанный маршрут:

Route::post('login')->name('api.auth.login')->uses('API\\Auth\\LoginController@login');

Вход в систему работает нормально при вызове через API, но делаетне сохранять сеанс в веб-представлении.

1 Ответ

0 голосов
/ 17 декабря 2018

Решено с помощью решения Hypnopompia в этом выпуске GitHub: https://github.com/laravel/passport/issues/135

Извлек его код и просто вставил его в промежуточное ПО web.

namespace App\Http\Middleware;

use Auth;
use Closure;
use DB;
use Laravel\Passport\Passport;
use Lcobucci\JWT\Parser;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use Lcobucci\JWT\ValidationData;

class ApiTokenWebLogin
{
    /**
     * @param string $tokenId
     *
     * @return mixed
     */
    private function isAccessTokenRevoked($tokenId)
    {
        return DB::table('oauth_access_tokens')
            ->where('id', $tokenId)
            ->where('revoked', 1)
            ->exists();
    }

    /**
     * @param string $jwt
     *
     * @return array|bool
     */
    private function validateToken($jwt)
    {
        try {
            $token = (new Parser())->parse($jwt);

            if ($token->verify(new Sha256(), file_get_contents(Passport::keyPath('oauth-public.key'))) === false) {
                return false;
            }

            // Ensure access token hasn't expired.
            $data = new ValidationData();
            $data->setCurrentTime(time());

            if ($token->validate($data) === false) {
                return false;
            }

            // Check if token has been revoked.
            if ($this->isAccessTokenRevoked($token->getClaim('jti'))) {
                return false;
            }

            return [
                'user_id' => $token->getClaim('sub'),
            ];
        } catch (\Exception $e) {
            return false; // Decoder error.
        }
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     *
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $token = $request->bearerToken();

        // If user passed a valid Passport token, then login to the webview.
        if (!empty($token) && $request->hasSession() && !Auth::check() && $user_id = $this->validateToken($token)) {
            \Auth::loginUsingId($user_id);
        }

        return $next($request);
    }
}
...