权限控制

现在支持:

  • BasicAuth
  • BearerToken (JWT)
  • ACL

安装:

  1. composer require swoft/auth

使用

本组件目前实现了 BasicAuthBearerToken 的验证,以及简单的 ACL,使用方法简单,在 config/beans/base.php 中的 serverDispatcher.middlewares 里 添加 \Swoft\Auth\Middleware\AuthMiddleware::class 中间件,如下

  1. 'serverDispatcher' => [
  2. 'middlewares' => [
  3. \Swoft\Auth\Middleware\AuthMiddleware::class,
  4. ]
  5. ],

然后在配置文件 config/properties/app.php 中添加

  1. 'auth' => [
  2. 'jwt' => [
  3. 'algorithm' => 'HS256',
  4. 'secret' => '1231231'
  5. ],
  6. ],
  • 注意 secret 不要使用上述值,修改为你自己的值

配置验证管理 AuthManagerInterface

AuthManager 是登录验证的核心,本类实现了 Token 的验证及缓存,你可以继承这个类实现多种方式登录(配合accountType实现),下面就是一个 basicAuthDemo

首先实现一个 Swoft\Auth\Mapping\AccountTypeInterface 作为我们登录的通道

  1. use Swoft\Auth\Mapping\AccountTypeInterface;
  2. use Swoft\Auth\Bean\AuthResult;
  3. /**
  4. * @Bean()
  5. */
  6. class AdminNormalAccount implements AccountTypeInterface
  7. {
  8. /**
  9. * @Inject()
  10. * @var AdminUserDAO
  11. */
  12. protected $dao;
  13. const ROLE = 'role';
  14. /**
  15. * @throws \Swoft\Db\Exception\DbException
  16. */
  17. public function login(array $data) : AuthResult
  18. {
  19. $identity = $data['identity'];
  20. $credential = $data['credential'];
  21. $user = $this->dao::findOneByUsername($identity);
  22. $result = new AuthResult();
  23. if($user instanceof AdminUserBean && $user->verify($credential)){
  24. $result->setExtendedData([self::ROLE => $user->getIsAdministrator()]);
  25. $result->setIdentity($user->getId());
  26. }
  27. return $result;
  28. }
  29. /**
  30. * @throws \Swoft\Db\Exception\DbException
  31. */
  32. public function authenticate(string $identity) : bool
  33. {
  34. return $this->dao::issetUserById($identity);
  35. }
  36. }

然后在我们自己的 AuthManagerService 实现这个登录

  1. use Swoft\Auth\AuthManager;
  2. use Swoft\Auth\Mapping\AuthManagerInterface;
  3. use Swoft\Auth\Bean\AuthSession;
  4. /**
  5. * @Bean()
  6. */
  7. class AuthManagerService extends AuthManager implements AuthManagerInterface
  8. {
  9. /**
  10. * @var string
  11. */
  12. protected $cacheClass = Redis::class;
  13. /**
  14. * @var bool 开启缓存
  15. */
  16. protected $cacheEnable = true;
  17. public function adminBasicLogin(string $identity, string $credential) : AuthSession
  18. {
  19. return $this->login(AdminNormalAccount::class, [
  20. 'identity' => $identity,
  21. 'credential' => $credential
  22. ]);
  23. }
  24. }

然后在 config/beans/base.php 中把系统默认的 AuthManager Bean 替换为我们自己的 AuthManagerService,添加如下代码进行替换

  1. \Swoft\Auth\Mapping\AuthManagerInterface::class => [
  2. 'class'=>App\Domain\User\Service\AuthManagerService::class
  3. ],

现在我们就可以在一个 Controller 中使用刚才实现的登录方式了

  1. use Swoft\Auth\Constants\AuthConstants;
  2. use Swoft\Http\Message\Server\Request;
  3. use Swoft\Http\Server\Bean\Annotation\Controller;
  4. use Swoft\Http\Server\Bean\Annotation\RequestMapping;
  5. use Swoft\Http\Server\Bean\Annotation\RequestMethod;
  6. use Swoft\Auth\Mapping\AuthManagerInterface;
  7. /**
  8. * @Controller(prefix="/oauth")
  9. */
  10. class AuthorizationsResource
  11. {
  12. /**
  13. * @RequestMapping(route="token", method={RequestMethod::POST})
  14. */
  15. public function oauth(Request $request) : array
  16. {
  17. $identity = $request->getAttribute(AuthConstants::BASIC_USER_NAME) ?? '';
  18. $credential = $request->getAttribute(AuthConstants::BASIC_PASSWORD) ?? '';
  19. if(!$identity || !$credential){
  20. return [
  21. "code" => 400,
  22. "message" => "Identity and Credential are required."
  23. ];
  24. }
  25. /** @var AuthManagerService $manager */
  26. $manager = App::getBean(AuthManagerInterface::class);
  27. /** @var AuthSession $session */
  28. $session = $manager->adminBasicLogin($identity, $credential);
  29. $data = [
  30. 'token' => $session->getToken(),
  31. 'expire' => $session->getExpirationTime()
  32. ];
  33. return $data;
  34. }
  35. }

现在可以通过 Postman 或 其它请求方式 请求我们的登录接口了