Advertisement
Guest User

Untitled

a guest
Feb 27th, 2020
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.81 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement