2019独角兽企业重金招聘Python工程师标准>>>

一.本地user登录

1. 定义一个User

<?phpnamespace AppBundle\Document;use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Symfony\Component\Security\Core\User\UserInterface;/*** @MongoDB\Document(collection="user")*/
class User implements UserInterface, \Serializable
{/*** @MongoDB\Id(strategy="auto")*/private $id;/*** @MongoDB\Field(type="string")*/private $username;/*** @MongoDB\Field(type="string")*/private $password;/*** @MongoDB\Field(type="string")*/private $email;/*** @var boolean* @MongoDB\Field(type="boolean")*/private $isActive;....

2. 自定义user provide

    <?phpnamespace AppBundle\Provide;use Doctrine\ODM\MongoDB\DocumentManager;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;class UserProvide implements UserProviderInterface
{/*** @var DocumentManager*/protected $dm;public function __construct(DocumentManager $dm){$this->dm = $dm;}/*** Loads the user for the given username.** This method must throw UsernameNotFoundException if the user is not* found.** @param string $username The username** @return UserInterface** @throws UsernameNotFoundException if the user is not found*/public function loadUserByUsername($username){$user = $this->dm->getRepository("AppBundle:User")->findOneBy(array('username'=>$username));if ($user) {return $user;}throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));}/*** Refreshes the user for the account interface.** It is up to the implementation to decide if the user data should be* totally reloaded (e.g. from the database), or if the UserInterface* object can just be merged into some internal array of users / identity* map.** @param UserInterface $user** @return UserInterface** @throws UnsupportedUserException if the account is not supported*/public function refreshUser(UserInterface $user){if (!$user instanceof UserInterface) {throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));}return $this->loadUserByUsername($user->getUsername());}/*** Whether this provider supports the given user class.** @param string $class** @return bool*/public function supportsClass($class){return $class === 'AppBundle\Document\User';}
}
    // services.ymlapp.user.provide:class: AppBundle\Provide\UserProvidearguments:- "@doctrine.odm.mongodb.document_manager"

二. 其他方式认证(这里用另一个user表验证)

###1.TestUser

namespace AppBundle\Document;use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use Symfony\Component\Security\Core\User\UserInterface;/*** @MongoDB\Document(collection="test_user")*/
class TestUser implements UserInterface, \Serializable
{/*** @MongoDB\Id(strategy="auto")*/private $id;/*** @MongoDB\Field(type="string")*/private $username;/*** @MongoDB\Field(type="string")*/private $password;/*** @MongoDB\Field(type="string")*/private $email;...

###2. TestUserProvide

<?phpnamespace AppBundle\Provide;use Doctrine\ODM\MongoDB\DocumentManager;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;class TestUserProvide implements UserProviderInterface
{/*** @var DocumentManager*/protected $dm;public function __construct(DocumentManager $dm){$this->dm = $dm;}/*** Loads the user for the given username.** This method must throw UsernameNotFoundException if the user is not* found.** @param string $username The username** @return UserInterface** @throws UsernameNotFoundException if the user is not found*/public function loadUserByUsername($username){$user = $this->dm->getRepository("AppBundle:TestUser")->findOneBy(array('username'=>$username));if ($user) {return $user;}throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));}/*** Refreshes the user for the account interface.** It is up to the implementation to decide if the user data should be* totally reloaded (e.g. from the database), or if the UserInterface* object can just be merged into some internal array of users / identity* map.** @param UserInterface $user** @return UserInterface** @throws UnsupportedUserException if the account is not supported*/public function refreshUser(UserInterface $user){if (!$user instanceof UserInterface) {throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));}return $this->loadUserByUsername($user->getUsername());}/*** Whether this provider supports the given user class.** @param string $class** @return bool*/public function supportsClass($class){return $class === 'AppBundle\Document\TestUser';}
}
    //services.ymlapp.test_user.provide:class: AppBundle\Provide\TestUserProvidearguments:- "@doctrine.odm.mongodb.document_manager"

3.创建自定义Authentication Token

<?phpnamespace AppBundle\Security\Authentication\Token;use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;class TestToken extends AbstractToken
{/*** @param array $roles*/public function __construct(array $roles = array()){parent::__construct($roles);$this->setAuthenticated(count($roles) > 0);}/*** Returns the user credentials.** @return mixed The user credentials*/public function getCredentials(){return '';}
}

###4.创建自定义Authentication Provide

<?phpnamespace AppBundle\Security\Authentication\Provide;use AppBundle\Security\Authentication\Token\TestToken;
use AppBundle\Security\TestUserAuthenticate;
use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserProviderInterface;class TestProvide implements AuthenticationProviderInterface
{protected  $userProvider;protected  $testUserAuthenticate;/*** @param UserProviderInterface $userProvider*/public function __construct(UserProviderInterface $userProvider,TestUserAuthenticate $testUserAuthenticate){$this->userProvider = $userProvider;$this->testUserAuthenticate =  $testUserAuthenticate;}/*** Attempts to authenticate a TokenInterface object.** @param TokenInterface $token The TokenInterface instance to authenticate** @return TokenInterface An authenticated TokenInterface instance, never null** @throws AuthenticationException if the authentication fails*/public function authenticate(TokenInterface $token){$user = $this->userProvider->loadUserByUsername($token->getUsername());if ($user && $this->testUserAuthenticate->isAuthenticationValid($user,$token->getUsername(),$token->getCredentials())) {$authenticatedToken = new TestToken($user->getRoles());$authenticatedToken->setUser($user);return $authenticatedToken;}throw new AuthenticationException('The test authentication failed.');}/*** Checks whether this provider supports the given token.** @param TokenInterface $token A TokenInterface instance** @return bool true if the implementation supports the Token, false otherwise*/public function supports(TokenInterface $token){return $token instanceof TestToken || $token instanceof UsernamePasswordToken ;}
}

###5.验证输入的密码是否正确(注意上面第4步isAuthenticationValid方法)

<?phpnamespace AppBundle\Security;use Doctrine\ODM\MongoDB\DocumentManager;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;class TestUserAuthenticate
{/*** @var EncoderFactoryInterface*/protected $encoderFactory;/*** @var DocumentManager*/protected $dm;public function __construct(DocumentManager $dm,EncoderFactoryInterface $encoderFactory){$this->dm = $dm;$this->encoderFactory = $encoderFactory;}public function isAuthenticationValid($user,$username,$password){$password = $this->encoderFactory->getEncoder($user)->encodePassword($password,$user->getSalt());$result = $this->dm->getRepository('AppBundle:TestUser')->findOneBy(array('username'=>$username,'password'=>$password));if(empty($result)){return false;}else{return true;}}
}

6.创建自己的factory

<?phpnamespace AppBundle\DependencyInjection\Security\Factory;use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\FormLoginFactory;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Reference;class TestFactory extends  FormLoginFactory
{/*** @param ContainerBuilder $container* @param string $id* @param array $config* @param string $userProviderId* @return string*/protected function createAuthProvider(ContainerBuilder $container, $id, $config, $userProviderId){$providerId = 'security.authentication.provider.test.' . $id;$container->setDefinition($providerId, new DefinitionDecorator('app.test.security.authentication.provider'))->replaceArgument(0, new Reference($userProviderId));return $providerId;}/*** @return string*/public function getPosition(){return 'form';}/*** @return string*/public function getKey(){return 'test-login';}
}

7.在security context增加自定义的factory

<?phpnamespace AppBundle;use AppBundle\DependencyInjection\Security\Factory\TestFactory;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;class AppBundle extends Bundle
{public function build(ContainerBuilder $container){parent::build($container);$extension = $container->getExtension('security');$extension->addSecurityListenerFactory(new TestFactory());}
}

8.完整的services.yml

services:app.user.provide:class: AppBundle\Provide\UserProvidearguments:- "@doctrine.odm.mongodb.document_manager"app.test.authentivate:class: AppBundle\Security\TestUserAuthenticatearguments:- "@doctrine.odm.mongodb.document_manager"- "@security.encoder_factory"app.test_user.provide:class: AppBundle\Provide\TestUserProvidearguments:- "@doctrine.odm.mongodb.document_manager"app.test.security.authentication.provider:class: AppBundle\Security\Authentication\Provide\TestProvidearguments:- ''- '@app.test.authentivate'

9.完整的security.yml

security:encoders:AppBundle\Document\User: plaintextAppBundle\Document\TestUser: plaintextproviders:chain_provider:chain:providers: [user_provider,test_user_provider]user_provider:id: app.user.providetest_user_provider:id: app.test_user.providefirewalls:dev:pattern: ^/(_(profiler|wdt)|css|images|js)/security: falsemain:test_login:provider: test_user_providerlogin_path: logincheck_path: logindefault_target_path: homepageform_login:provider: user_providerlogin_path: logincheck_path: logindefault_target_path: homepagelogout:path:   logouttarget: loginanonymous: ~

三.小结

按照上面的步骤就能实现在一个输入框通过两种不同的方式登录。如果在项目运行的过程中,只需要本地的User,这个实现也很简单,只需要在自定义的第三方的UserProvide里面返回本地User就可以了,思路如下:

// TestUserProvide
public function loadUserByUsername($username){//$user = $this->dm->getRepository("AppBundle:TestUser")->findOneBy(array('username'=>$username));//if ($user) {//  return $user;//}//1.验证输入的用户名在第三方系统中正确,并返回用户信息(TestUser)//2.查看本地数据库是否存在该用户名的用户,如果有直接返回User,没有,根据TestUser的信息新建一个User,存储到本地,返回新创建的User//3.此时虽然不同用户登录时使用的Token不一样,但是$token->getUser()取的都是本地User对象的实例throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));}

转载于:https://my.oschina.net/u/925519/blog/685087

一个登录框实现不同的登录验证相关推荐

  1. win10锁屏或睡眠一段时间后弹不出登录框

    win10锁屏或睡眠一段时间后弹不出登录框 文:铁乐与猫 通常发生在win10更新到10周年版后发生,也就是会卡在登录状态,但不见输入登录框. 我出现这种情况的时候不是很严重,一般等久些也能出现,但问 ...

  2. SharePoint 客户端经常弹出Windows验证登录框问题

    场景描述: Site工作人员UserA创建了一个Task,并且Assign给UserB.UserB接到来自Task List的邮件通知.这时UserA发现Assign的人错了,重新修改Task Ite ...

  3. 一个“登录框“引发的安全问题

    前言 搞安全的小伙伴只有一个登录框你都能测试哪些漏洞? 通常大家测试的都会测试关键部分,为了有更好的测试效果,小厂会提供给你用户名密码:但是一些比较重要的企业,而这个环境却是正式环境,里面存放着一些数 ...

  4. python登陆界面代码_Python-PyQt5-第一个小项目--登录框--login

    Ps:水平有限,欢迎建议和挑错 我们在此之前,学习了PyQt的主窗口(QMainwindow),按钮(Qpushbutton),标签栏(QLabel),文本框编辑框(LineEdit)4个组件. 我们 ...

  5. 一个登录框引发的“安全问题”

    一个文本框可能存在哪些漏洞 前言 用户名枚举 弱口令 空口令 登录认证绕过 存在暴力破解风险 图形验证码不失效 短信验证码绕过 短信验证码可暴力破解 短信验证码可预测 短信炸弹 恶意锁定问题 密码明文 ...

  6. HTML写一个登录框样式

    以QQ空间的登陆框为例,原先的代码很复杂,还涉及了其他的知识,对于刚刚接触的人来说想写一点点样式来练练手的话可以看一下. 写好之后是这个样子 下面是代码 <!DOCTYPE html> & ...

  7. pyqt5优秀项目python_Python-PyQt5-第一个小项目--登录框--login

    Ps:水平有限,欢迎建议和挑错 我们在此之前,学习了PyQt的主窗口(QMainwindow),按钮(Qpushbutton),标签栏(QLabel),文本框编辑框(LineEdit)4个组件. 我们 ...

  8. 点击登录按钮,弹出一个登录框

    点击登录按钮,弹出一个登录框 首先将登录框写在一个div块里,里面放上登录框所需的各种信息,比如用户名.密码等,并将CSS样式里的display设置成none.然后在你的前端页面,比如index.ht ...

  9. 2022-05-10 实现一个可拖拽的弹出登录框

    文章目录 要求 思路 完整代码 坐标说明(复习) 效果: 重点代码 要求 点击文字弹出一个带有样式的登录框 按下登录框的标题区域,可以实现拖动 思路 先计算鼠标的移动距离=移动的坐标-按下的坐标再计算 ...

最新文章

  1. python3+requests库框架设计08-发送邮件
  2. ajax查询数据返回结果不变
  3. Java8 HashMap源码分析
  4. Android——SMS接收发短信与运行权限
  5. Mybatis知识(1)
  6. duet设置_一秒把平板变 PC 电脑的扩展屏幕:TwomonUSB Duet Display 对比评测
  7. 计算机毕业设计ssm基于vue的健康餐饮管理系统的设计与实现
  8. 英语四级口语考试计算机考吗,四级考试是不是要考口语(英语四级口语考试有必要报名吗?)...
  9. Resource temporarily unavailable
  10. 物联网如何测试(一)
  11. 戴尔灵越15-5567装黑苹果
  12. 玩玩小程序:使用 WebApi 交互打造原生的微信小程序 - 图灵小书架
  13. 基于c语言的语法分析器的实现
  14. PHP简介和基础案例
  15. (你也可以像别人一样对框架底层源码来去自如)23种设计模式之外观模式
  16. KDYD-JC自动高压漆膜连续性试验仪
  17. 小学 计算机阅卷,小学生考试也使用网上阅卷了,公平吗?
  18. 【达梦数据库】数据实时同步软件 + 数据对比工具
  19. 88hinews.cn bbs.php,BBS(php mysql)完整版(八)
  20. Python 玩转《生僻字》

热门文章

  1. LSI IOC,ROC,HBA,Raid Adapter
  2. 2011年的32有用的jQuery插件
  3. 某港企高管:将孩子送出去吧!
  4. 数据中心未来会被以太网交换器商用IC占领吗?
  5. Android开发:关于WebView
  6. Metasploit***技巧:后***Meterpreter代理
  7. Windows 8.1安装.net 3.5功能
  8. winform中的webbrowser里面操作html代码问题
  9. 两个小技巧,马上加快上网速度
  10. iOS开发JSON字符串和字典互转