SHARE
TWEET

Untitled

a guest Feb 27th, 2020 62 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2.  
  3. namespace Redmix0901\Oauth2Sso\Http\Middleware;
  4.  
  5. use Closure;
  6. use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
  7. use Illuminate\Http\JsonResponse;
  8. use Illuminate\Http\Response;
  9. use Illuminate\Contracts\Config\Repository as Config;
  10. use Illuminate\Support\Facades\Cookie;
  11. use Illuminate\Support\Facades\Event;
  12. use Illuminate\Support\Facades\Request;
  13. use Redmix0901\Oauth2Sso\SingleSignOn;
  14.  
  15. class OAuth2SsoMiddleware
  16. {
  17.     /**
  18.      *@var string
  19.      */
  20.     const ACTION_REDIRECT_WITH_ALL = 'redirect_with_all';
  21.  
  22.     /**
  23.      *@var string
  24.      */
  25.     const ACTION_REDIRECT_IF_LOGIN = 'redirect_if_login';
  26.  
  27.     /**
  28.      *@var string
  29.      */
  30.     const ACTION_CREATE_COOKIE = 'cookie';
  31.  
  32.     /**
  33.      *@var \Redmix0901\Oauth2Sso\SingleSignOn
  34.      */
  35.     protected $singleSignOn;
  36.  
  37.     /**
  38.      *
  39.      * @var Illuminate\Contracts\Config\Repository
  40.      */
  41.     protected $config;
  42.  
  43.     /**
  44.      * OAuth2SsoMiddleware constructor.
  45.      *
  46.      * @param Repository $config
  47.      * @param SingleSignOn $singleSignOn
  48.      */
  49.     public function __construct(SingleSignOn $singleSignOn, Config $config)
  50.     {
  51.         $this->config = $config;
  52.         $this->singleSignOn = $singleSignOn;
  53.     }
  54.  
  55.     /**
  56.      * Handle an incoming request.
  57.      *
  58.      * @param  \Illuminate\Http\Request  $request
  59.      * @param  \Closure  $next
  60.      * @param  string[]  ...$action
  61.      * @return mixed
  62.      *
  63.      * @throws \IdentityProviderException
  64.      */
  65.     public function handle($request, Closure $next, ...$action)
  66.     {
  67.         if (empty($action)) {
  68.             $action = [null];
  69.         }
  70.        
  71.         /**
  72.          *
  73.          * @var \League\OAuth2\Client\Token\AccessToken $accessToken
  74.          */
  75.         $accessToken = $this->singleSignOn->getAccessTokenLocal();
  76.  
  77.         /**
  78.          * Không có $accessToken tồn tại.
  79.          */
  80.         if (!$accessToken) {
  81.             return $this->redirectTo($request, $next, $action);
  82.         }
  83.  
  84.         try {
  85.  
  86.             /**
  87.              * Xem $accessToken hết hạn sử dụng chưa.
  88.              * Nếu hết hạn sẽ lấy $accessToken và
  89.              * refresh token mới bằng refresh token hiện tại.
  90.              */
  91.             $accessToken = $this->singleSignOn->refreshTokenIfExpired($accessToken);
  92.  
  93.             /**
  94.              * Kiểm tra bằng cách lấy resource owner bằng $accessToken.
  95.              */
  96.             $resourceOwner = $this->singleSignOn->getUserByToken($accessToken);
  97.  
  98.         } catch (IdentityProviderException $e) {
  99.  
  100.             /**
  101.              * Xóa $accessToken trên session nếu có lỗi.
  102.              */
  103.             $this->singleSignOn->deleteAccessTokenLocal();
  104.  
  105.             return $this->redirectTo($request, $next, $action);
  106.         }
  107.  
  108.         $user = $resourceOwner->toArray();
  109.  
  110.         if (isset($user['message']) && $user['message'] == 'Unauthenticated.') {
  111.             /**
  112.              * Xóa $accessToken trên session nếu có lỗi.
  113.              */
  114.             $this->singleSignOn->deleteAccessTokenLocal();
  115.  
  116.             return $this->redirectTo($request, $next, $action);
  117.         }
  118.        
  119.         $request->attributes->add(['oauth2_user' => $resourceOwner]);
  120.  
  121.         return $this->sendReponse($request, $next, $action);
  122.     }
  123.  
  124.     /**
  125.      * Trả về reponse sau khi tạo mới token.
  126.      *
  127.      * Token sẽ được gắn trên cookie nếu có yêu cầu và hợp lệ.
  128.      *
  129.      * @param  \Illuminate\Http\Request  $request
  130.      * @param  \Illuminate\Http\Response  $response
  131.      * @param  string[]  ...$action
  132.      * @return \Illuminate\Http\Response
  133.      */
  134.     protected function sendReponse($request, $next, $action)
  135.     {
  136.         if ($this->shouldReceiveFreshAccessToken($request, $next, $action)) {
  137.  
  138.             $config = $this->config->get('session');
  139.  
  140.             /**
  141.              *
  142.              * @var \League\OAuth2\Client\Token\AccessToken $accessToken
  143.              */
  144.             $accessToken = $this->singleSignOn->getAccessTokenLocal();
  145.  
  146.             return $next($request)->withCookie(
  147.                 cookie(
  148.                     SingleSignOn::cookie(),
  149.                     $accessToken->getToken(),
  150.                     $config['lifetime']
  151.                 )
  152.             );
  153.         } elseif (Request::hasCookie(SingleSignOn::cookie())) {
  154.             Cookie::queue(Cookie::forget(SingleSignOn::cookie()));
  155.         }
  156.  
  157.         return $next($request);
  158.     }
  159.  
  160.     /**
  161.      * Quyết định xem có được gắn token vào cookie hay không.
  162.      *
  163.      * @param  \Illuminate\Http\Request  $request
  164.      * @param  \Illuminate\Http\Response  $response
  165.      * @param  string[]  ...$action
  166.      * @return bool
  167.      */
  168.     protected function shouldReceiveFreshAccessToken($request, $next, $action)
  169.     {
  170.         /**
  171.          *
  172.          * @var \League\OAuth2\Client\Token\AccessToken $accessToken
  173.          */
  174.         $accessToken = $this->singleSignOn->getAccessTokenLocal();
  175.  
  176.         return in_array(self::ACTION_CREATE_COOKIE, $action)
  177.                     && $request->isMethod('GET')
  178.                     && !empty($accessToken)
  179.                     && !$accessToken->hasExpired();
  180.     }
  181.  
  182.     /**
  183.      * Kiểm tra token có tồn tại trên cookie chưa.
  184.      *
  185.      * @param  \Illuminate\Http\Response  $response
  186.      * @return bool
  187.      */
  188.     protected function alreadyContainsToken($response)
  189.     {
  190.         foreach ($response->headers->getCookies() as $cookie) {
  191.             if ($cookie->getName() === SingleSignOn::cookie()) {
  192.                 return true;
  193.             }
  194.         }
  195.  
  196.         return false;
  197.     }
  198.  
  199.     /**
  200.      * Redirect về Auth nếu có yêu cầu.
  201.      *
  202.      * Hoặc tiếp tục request với tạo token trên cookie.
  203.      *
  204.      * @param  \Illuminate\Http\Request  $request
  205.      * @param  \Illuminate\Http\Response  $response
  206.      * @param  string[]  ...$action
  207.      * @return redirect
  208.      */
  209.     protected function redirectTo($request, $next, $action)
  210.     {
  211.         /**
  212.          * Nếu có ACTION_REDIRECT_WITH_ALL trong $action thì sẽ redirect về Server Auth,
  213.          *
  214.          * kể cả đã hoặc chưa đăng nhập Server Auth.
  215.          */
  216.         if (in_array(self::ACTION_REDIRECT_WITH_ALL, $action)) {
  217.             return $this->singleSignOn->getAuthRedirect();
  218.         }
  219.  
  220.         /**
  221.          * Nếu có ACTION_REDIRECT_IF_LOGIN trong $action thì sẽ redirect về Server Auth,
  222.          *
  223.          * khi đã đăng nhập Server Auth.
  224.          */
  225.         if (in_array(self::ACTION_REDIRECT_IF_LOGIN, $action)) {
  226.             if ($this->singleSignOn->checkCookie()) {
  227.                 return $this->singleSignOn->getAuthRedirect();
  228.             }
  229.         }
  230.  
  231.         return $this->sendReponse($request, $next, $action);
  232.     }
  233. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top