sensiolabs / connect-bundle
Requires
- php: >=7.1.3
- symfonycorp/connect: ^6.3
Requires (Dev)
- symfony/phpunit-bridge: ^4.4|^5.0
- symfony/security-bundle: ^4.4|^5.0
Conflicts
- symfony/config: <4.2
- dev-master / 6.x-dev
- v6.2.0
- v6.1.0
- v6.0.1
- v6.0.0
- 5.1.x-dev
- v5.1.4
- v5.1.3
- v5.1.2
- v5.1.1
- v5.1.0
- 5.0.x-dev
- v5.0.4
- v5.0.3
- v5.0.2
- v5.0.0
- 4.3.x-dev
- v4.3.13
- v4.3.12
- v4.3.11
- v4.3.10
- v4.3.9
- v4.3.8
- v4.3.7
- v4.3.6
- v4.3.5
- v4.3.4
- v4.3.3
- v4.3.2
- v4.3.1
- v4.3.0
- v4.2.2
- v4.2.1
- v4.2.0
- v4.1.0
- v4.0.0
- v3.1.0
- v3.0.0
- v2.0.0
- v1.0.0
- dev-start-template-support
- dev-authenticator
This package is auto-updated.
Last update: 2020-07-22 21:04:44 UTC
README
关于
这是 SymfonyConnect SDK 的官方包。
安装
第1步:使用 Composer 安装 symfony/connect-bundle
$ composer require symfonycorp/connect-bundle
如果您未使用 Symfony Flex,请参考 此包的食谱 以启用它。
第2步:配置您的 .env.local
文件
SYMFONY_CONNECT_APP_ID='Your app id' SYMFONY_CONNECT_APP_SECRET='Your app secret'
使用方法
使用 SymfonyConnect 认证用户
第1步:配置安全设置
注意:如果您想持久化用户,请阅读 食谱 部分。
如果您不想持久化用户,可以使用 ConnectInMemoryUserProvider
# config/packages/security.yaml security: providers: symfony_connect: connect_memory: ~ firewalls: # [...] secured_area: pattern: ^/ symfony_connect: check_path: symfony_connect_callback login_path: symfony_connect_login failure_path: home # need to be adapted to your config, see step 4 remember_me: false provider: symfony_connect anonymous: true
您也可以为某些用户加载特定的角色
# config/packages/security.yaml security: providers: symfony_connect: connect_memory: users: 90f28e69-9ce9-4a42-8b0e-e8c7fcc27713: "ROLE_CONNECT_USER ROLE_ADMIN"
注意:用户名是用户 uuid。
第2步:将一些链接添加到您的模板中
您可以生成指向 SymfonyConnect 登录页面的链接
<a href="{{ url('symfony_connect_login') }}">Connect</a>
您也可以指定登录后的目标 URL
<a href="{{ url('symfony_connect_login') }}?target=XXX">Connect</a>
第3步:与用户交互
API 用户可通过令牌存储访问,您可以通过自动注入 Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface $tokenStorage
获取。
$user = $tokenStorage->getToken()->getApiUser();
如果您使用内置的安全组件,您可以直接通过自动注入 SymfonyCorp\Connect\Api\Api $api
访问根 API
$user = $api->getRoot()->getCurrentUser();
您还可以通过显式提供访问令牌来获取对 API 根对象的访问权限
$accessToken = $tokenStorage->getToken()->getAccessToken(); $api->setAccessToken($accessToken); $root = $api->getRoot(); $user = $root->getCurrentUser();
第4步:处理失败
在 OAuth 舞蹈过程中可能会出现一些错误,例如用户可以拒绝您的应用程序或您在 symfony_connect.yaml
中定义的范围可能与在 SymfonyConnect 上创建应用程序时选择的不同。这些失败由默认的 Symfony 失败处理处理。
因此,如果发生错误,错误将存储在会话中(回退到查询属性),并将用户重定向到在 security.yaml
中防火墙的 symfony_connect
部分的 failure_path
节中指定的路由/路径。
警告:您需要指定
failure_path
。如果您不指定,用户将被重定向回login_path
,这意味着将启动 SymfonyConnect 认证并将用户重定向到 SymfonyConnect,这可能导致重定向循环。
这意味着如果您有认证错误,需要获取并在视图中显示它。这类似于您在 Symfony 中对典型登录表单所做的事情(这里我们假设您有一个指向以下控制器的 home
路由)
// src/Controller/HomeController.php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Security; class HomeController extends AbstractController { /** * @Route("/", name="home") */ public function home(Request $request) { $session = $request->hasSession() ? $request->getSession() : null; // get the authentication error if there is one if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) { $error = $request->attributes->get(Security::AUTHENTICATION_ERROR); } elseif (null !== $session && $session->has(Security::AUTHENTICATION_ERROR)) { $error = $session->get(Security::AUTHENTICATION_ERROR); $session->remove(Security::AUTHENTICATION_ERROR); } else { $error = ''; } return $this->render('home.html.twig', ['error' => $error]); } }
然后调整您的 twig 模板
{# templates/home.html.twig #} {% if app.user %} Congrats! You are authenticated with SymfonyConnect {% elseif error %} {{ error.messageKey | trans(error.messageData, 'security') }} {% else %} <a href="{{ url('symfony_connect_login') }}">Log in with SymfonyConnect</a> {% endif %}
食谱
如何持久化用户
步骤 1 - 创建 User
实体
<?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; use SymfonyCorp\Connect\Api\Entity\User as ConnectApiUser; use Symfony\Component\Security\Core\User\UserInterface; /** * @ORM\Table(name="user") * @ORM\Entity(repositoryClass="App\Repository\UserRepository") */ class User implements UserInterface { /** @ORM\Column(type="integer") @ORM\Id @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** @ORM\Column(type="string", length=255) */ private $uuid; /** @ORM\Column(type="string", length=255) */ private $username; /** @ORM\Column(type="string", length=255) */ private $name; public function __construct($uuid) { $this->uuid = $uuid; } public function updateFromConnect(ConnectApiUser $apiUser) { $this->username = $apiUser->getUsername(); $this->name = $apiUser->getName(); } public function getUuid() { return $this->uuid; } public function getUsername() { return $this->username; } public function getName() { return $this->name; } public function getRoles() { return ['ROLE_USER']; } public function getPassword() { } public function getSalt() { } public function eraseCredentials() { } }
步骤 2 - 创建仓库
<?php namespace App\Repository; use App\Entity\User; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Symfony\Component\Security\Core\Exception\UnsupportedUserException; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; class UserRepository extends ServiceEntityRepository implements UserProviderInterface { public function __construct(RegistryInterface $registry) { parent::__construct($registry, User::class); } public function loadUserByUsername($uuid) { return $this->findOneByUuid($uuid) ?: new User($uuid); } public function refreshUser(UserInterface $user) { if (!$user instanceof User) { throw new UnsupportedUserException(sprintf('class %s is not supported', get_class($user))); } return $this->loadUserByUsername($user->getUuid()); } public function supportsClass($class) { return User::class === $class; } }
别忘了更新您的数据库。
步骤 3 - 创建事件监听器
<?php namespace App\EventListener; use Doctrine\ORM\EntityManagerInterface; use SymfonyCorp\Connect\Security\Authentication\Token\ConnectToken; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony\Component\Security\Http\SecurityEvents; class SecurityInteractiveLoginListener implements EventSubscriberInterface { private $em; public function __construct(EntityManagerInterface $em) { $this->em = $em; } public function registerUser(InteractiveLoginEvent $event) { $token = $event->getAuthenticationToken(); if (!$token instanceof ConnectToken) { return; } $user = $token->getUser(); $user->updateFromConnect($token->getApiUser()); $this->em->persist($user); $this->em->flush($user); } public static function getSubscribedEvents() { return [ SecurityEvents::INTERACTIVE_LOGIN => 'registerUser', ]; } }
步骤 4 - 配置安全
# config/packages/security.yaml security: encoders: App\Entity\User: plaintext providers: symfony_connect: id: App\Repository\UserRepository
步骤 5 - 享受
如果您想的话,可以存储更多内容。但别忘了更新您的应用程序作用域。
许可
此软件包受 MIT 许可协议许可。