AuthServiceCookieTest.php 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. <?php
  2. use App\Services\AuthService;
  3. use Illuminate\Foundation\Testing\RefreshDatabase;
  4. use Illuminate\Http\Request;
  5. use Illuminate\Support\Str;
  6. uses(RefreshDatabase::class);
  7. /**
  8. * `AuthService::current()` 不再认 cookie。
  9. *
  10. * 曾经的那条回落(拿不到 bearer 就读 `$_COOKIE['user_uid']` 并直接返回)是 v1
  11. * 时代的遗留,不验签名、不验过期、不查库——浏览器里手工种一个就能冒充任何人。
  12. *
  13. * **必须直接操作 `$_COOKIE` 超全局。** Laravel 的 `withUnencryptedCookies()` 只填
  14. * Symfony Request 的 cookie 袋子,不碰超全局(`Request::create()` 不调
  15. * `overrideGlobals()`),所以用那个助手写出来的"cookie 测试"是空转的——
  16. * 不管代码里有没有这条分支都会过。
  17. */
  18. function withCookieSuperglobal(array $cookies, callable $fn): mixed
  19. {
  20. $backup = $_COOKIE;
  21. $_COOKIE = $cookies;
  22. try {
  23. return $fn();
  24. } finally {
  25. $_COOKIE = $backup;
  26. }
  27. }
  28. it('authenticates a valid bearer token', function () {
  29. $uid = (string) Str::uuid();
  30. $user = AuthService::current(Request::create('/', 'GET', server: [
  31. 'HTTP_AUTHORIZATION' => 'Bearer '.userToken($uid, 7),
  32. ]));
  33. expect($user)->toBe(['user_uid' => $uid, 'user_id' => 7]);
  34. });
  35. it('rejects a cookie with no bearer token', function () {
  36. $result = withCookieSuperglobal(
  37. ['user_uid' => (string) Str::uuid(), 'user_id' => '1'],
  38. fn () => AuthService::current(Request::create('/', 'GET'))
  39. );
  40. expect($result)->toBeFalse();
  41. });
  42. it('ignores the cookie even when the bearer token is invalid', function () {
  43. // 旧代码是 if(bearer){...} elseif(cookie){...},bearer 无效时走的是 if 分支
  44. // 里的 return false,本来就到不了 cookie;这条守的是将来别有人把顺序改回来
  45. $result = withCookieSuperglobal(
  46. ['user_uid' => (string) Str::uuid(), 'user_id' => '1'],
  47. fn () => AuthService::current(Request::create('/', 'GET', server: [
  48. 'HTTP_AUTHORIZATION' => 'Bearer not-a-jwt',
  49. ]))
  50. );
  51. expect($result)->toBeFalse();
  52. });
  53. it('rejects a request with neither bearer nor cookie', function () {
  54. expect(AuthService::current(Request::create('/', 'GET')))->toBeFalse();
  55. });
  56. it('keeps v2 endpoints unreachable by cookie', function () {
  57. // 端到端:v2 的 like 列表需要登录才会富化 selected;带着 cookie 打过去,
  58. // 现在拿不到登录态了
  59. $uid = makeStudio('cookie-v2');
  60. $target = (string) Str::uuid();
  61. $json = withCookieSuperglobal(
  62. ['user_uid' => $uid, 'user_id' => '1'],
  63. fn () => $this->getJson("/api/v2/like?view=count&target_id={$target}")->json()
  64. );
  65. expect($json['ok'])->toBeTrue();
  66. });