代码之家  ›  专栏  ›  技术社区  ›  eComEvo

使用API调用将Laravel用户登录到进度Web应用程序

  •  0
  • eComEvo  · 技术社区  · 7 年前

    我已经通过移动应用程序的API为登录用户设置了Passport路由。但是,移动应用程序的一部分使用WebView显示封闭内容,另一部分则从API中提取其他内容。

    一旦用户使用API登录到应用程序,我需要他们同时登录到Web内容。

    但是,没有使用API创建会话。在显示WebView时,如何通过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调用登录时,登录工作正常,但不会将会话持久化到WebView中。

    1 回复  |  直到 7 年前
        1
  •  0
  •   eComEvo    7 年前

    在这个Github问题中使用Hypnopompia的解决方案解决了这个问题: 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);
        }
    }