mortimer333/api-skeleton

API 骨架

dev-master 2024-02-19 21:28 UTC

This package is auto-updated.

Last update: 2024-09-19 22:40:29 UTC


README

安全检查表

https://cheatsheetseries.owasp.ac.cn/index.html

Swagger

https://symfony.com.cn/bundles/NelmioApiDocBundle/current/index.html

  • 只有名称以 api. 开头的路由会在 Swagger 中显示

https://zircote.github.io/swagger-php/guide/attributes.html

nelmio/NelmioApiDocBundle#1990

https://swagger.org.cn/docs/specification/about/

安全性

https://symfony.com.cn/doc/current/security.html

  • #[CurrentUser] 属性不起作用,请使用 Symfony\Component\Security\Core\Security::getUser() 代替 - symfony/symfony#40333

CSRF 令牌

如果使用 API 平台,CSRF 令牌应由前端生成并添加到头中。让我们在用户登录时创建它,保存在 cookie 中并重复使用。它将在浏览器、系统、IP 中设置少量信息

  • 浏览器
  • 系统
  • IP

这将足以确定用户突然更改并注销。我们还将添加加盐的应用程序密钥用于 CSRF。

电子邮件验证

https://github.com/symfonycasts/verify-email-bundle

秘密

我们将使用 symfony vault - https://symfony.com.cn/doc/current/configuration/secrets.html

  • 在 dev 上可以从 config/secrets/dev/ 提交密钥
  • 永远不要提交私钥 - config/secrets/dev/dev.decrypt.private.php 在 PROD
    • 使用 APP_RUNTIME_ENV=prod php bin/console secrets:generate-keys 运行 prod
    • 通过 secrets:generate-keys --rotate 定期更改安全密钥的脚本
  • 要设置新环境: php bin/console secrets:set [名称]

固定装置

要重置测试数据库并填充新数据,请使用固定装置

APP_ENV=test php bin/console doctrine:fixtures:load

make reset-test-env

测试

我们使用 codeception(它是基于 PHPUint 的)

actor: ApiTester
modules:
  enabled:
    - REST:
        url: http://api.boardmeister.local/ # <-- url
        depends: Symfony
        part: Json
    - Symfony:
        app_path: 'src'
        environment: 'test'
  • 以 www-data 运行测试以避免权限问题: sudo runuser -u www-data make before-push
  • symfony 模块
  • 要创建测试,您必须运行
    • 对于单元测试: php vendor/bin/codecept generate:test Unit Dir/TestNameWithoutTestAtEnd
    • 对于集成测试: php vendor/bin/codecept generate:test Integration Dir/TestNameWithoutTestAtEnd
    • 对于 API 测试: php vendor/bin/codecept generate:test Api Dir/TestNameWithoutTestAtEnd
  • 运行测试: php vendor/bin/codecept run
  • 运行详细测试: php vendor/bin/codecept run --stepsphp vendor/bin/codecept run --debug
  • 运行带覆盖率: DEBUG_MODE=coverage php vendor/bin/codecept run --coverage --coverage-xml --coverage-html
  • 运行仅
    • 单元测试: php vendor/bin/codecept run Unit
    • 集成测试: php vendor/bin/codecept run Integration
    • API 测试: php vendor/bin/codecept run Api
    • 单次测试: php vendor/bin/codecept run Integration SigninCest.php 或完整路径 php vendor/bin/codecept run tests/acceptance/SigninCest.phphttps://codeception.com/docs/GettingStarted#running-tests
  • 实用知识
    • _before 在每个测试之前执行
    • _after 在每个测试后执行(如果没有错误发生)
    • _failed 在每个失败的测试后执行
    • _passed 在每个通过测试后执行
    • _inject 用于注入服务(https://codeception.com/docs/AdvancedUsage#dependency-injection
    • 要跳过测试,可以使用 #[Skip]https://codeception.com/docs/AdvancedUsage#skip-tests
    • 类似于控制器,您可以分组测试并运行分组(https://codeception.com/docs/AdvancedUsage#groups
      • 使用 Codeception\Attribute\Group;
      • #[Group('admin')]
      • php vendor/bin/codecept run -g admin -g editor
    • 而不是提供者,您可以使用 Examples: (https://codeception.com/docs/AdvancedUsage#examples-attribute
      • #[Examples('/api', 200)]
      • 或者如果您需要一个函数 #[DataProvider('pageProvider')]
    • 生成 JUnit XML 输出
      • php vendor/bin/codecept run --steps --xml --html
    • 断言
      • $this->assertEquals()
      • $this->assertContains()
      • $this->assertFalse()
      • $this->assertTrue()
      • $this->assertNull()
      • $this->assertEmpty()
    • 异常
      • $this->expectException(ValidationException::class);
      • $this->expectExceptionMessageMatches('#Nieprawidłowy typ marki#');

PHP Mess Detector

要抑制警告,使用 @SuppressWarnings(PHPMD.[warning name])

php vendor/bin/phpmd src text phpmd.xml
php vendor/bin/phpmd tests text phpmd.xml

PHP Stan

命令

php vendor/bin/phpstan analyse src tests

要忽略单个错误,使用

  • @phpstan-ignore-line
  • @phpstan-ignore-next-line

要忽略一系列错误,请考虑阅读 https://phpstan.org/user-guide/ignoring-errors 并更新 ./phpstan.neon

已知错误

Could not write file: /tmp/phpstan/resultCache.php (file_put_contents(/tmp/phpstan/resultCache.php): Failed to open stream: Permission denied)

如果您以前以非当前用户身份运行分析,则缓存目录可能具有错误的所有者。将所有者更改为当前用户,然后应该一切正常

PHP Code Style Fixer

vendor/bin/php-cs-fixer fix --verbose

配置选项 - https://mlocati.github.io/php-cs-fixer-configurator/#version:3.13

PHP Code Sniffer

要忽略

Psalm

要抑制警告 @psalm-suppress InvalidReturnType 更多信息请参阅 https://psalm.dev/docs/running_psalm/dealing_with_code_issues/

已知问题:无法创建缓存目录

Uncaught RuntimeException: PHP Error: mkdir(): Permission denied in /var/www/html/boardmeister_internal/vendor/vimeo/psalm/src/Psalm/Config.php:2210 for command with CLI args "vendor/bin/psalm --taint-analysis" in /var/www/html/boardmeister_internal/vendor/vimeo/psalm/src/Psalm/Internal/ErrorHandler.php:75

如果您以 www-data 运行命令,请确保已创建 /var/www/.cache 目录,并且 www-data 是其所有者。

PHP

Ubuntu - update-alternatives --config php

BCMath

在 php.ini 中将 bcmath.scale 设置为 2

JWT

https://jwt.node.org.cn/

Header 管理器

https://web-token.spomky-labs.com/the-components/header-checker

Claim 管理器

https://web-token.spomky-labs.com/the-components/claim-checker

密钥

  • https://web-token.spomky-labs.com/advanced-topics-1/security-recommendations
  • 对称算法
  • 256 位对称密钥和至少 2048 位 RSA 密钥
  • 密钥附加
    • kid:一个唯一的密钥 ID
    • use:指示密钥的使用。或者是 sig(签名/验证)或者是 enc(加密/解密)。
    • alg:允许与该密钥一起使用的算法。
  • 密钥轮换 - 每周一次
  • 令牌有效负载
    • 尽可能小
    • 拥有
      • jti - 唯一标识符
      • exp: 过期时间
      • iat: 签发时间
      • nbf: 时间的有效点。
      • iss (签发者)
      • aud (受众)
    • 当使用加密令牌时,iss 和 aud 声明应复制到头部

验证

  1. 反序列化令牌
  2. 对于每个签名/接收者(在使用 Json 常规序列化模式时可能发生)
    1. 检查完整头部(受保护的和未受保护的)
    2. 验证签名(JWS)或解密令牌(JWE)
    3. 检查有效载荷中的声明(如果有)

如果在处理过程中发生错误,应将令牌视为无效。

必须检查头部参数。您至少应检查 alg(算法)和 enc(仅适用于 JWE)参数。crit(关键)头部参数始终被检查。

嵌套令牌

我们想要使用嵌套令牌来签名和加密令牌 - https://web-token.spomky-labs.com/advanced-topics-1/nested-tokens