本文概述
- 怎么做
- 定制登录控制器示例
寻找使用你自己的代码从控制器登录用户?你找到了学习它的正确地方。在本文中, 你将学习如何在Symfony应用程序上自动登录用户(带有或不带有凭据)。
怎么做你首先需要在控制器中导入一些类, 即InteractiveLoginEvent和UsernamePasswordToken。然后, 使用Doctrine的实体管理器或FOSUserBundle的用户管理器自行查找用户。如果你使用的是FOSUser, 则用户应存储在变量中, 并且代表FOS \ UserBundle \ Model \ User的实例;如果不使用, 则仅表示User。接下来, 继续创建令牌并在令牌存储服务中进行设置。创建令牌的类期望将用户对象作为第一个参数, 因为第二个参数通常是用户的密码, 但是可以为null。作为第三个参数, 你需要提供要使用的防火墙的名称, 它通常是主要的, 但是如果有其他名称, 则值得检查你的security.yml文件。作为第四个参数, 你需要提供用户的角色。
你还需要将类生成的令牌存储在会话中, 最后手动调度交互式登录事件:
<
?phpnamespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class SomeController extends Controller{public function loginAction(Request $request){$user = /*The user needs to be registered */;
#// Example of how to obtain an user://$user = $this->
getDoctrine()->
getManager()->
getRepository("AppBundle/Entity/User")->
findOneBy(array('username' =>
"some user name example"));
//Handle getting or creating the user entity likely with a posted form// The third parameter "main" can change according to the name of your firewall in security.yml$token = new UsernamePasswordToken($user, null, 'main', $user->
getRoles());
$this->
get('security.token_storage')->
setToken($token);
// If the firewall name is not main, then the set value would be instead:// $this->
get('session')->
set('_security_XXXFIREWALLNAMEXXX', serialize($token));
$this->
get('session')->
set('_security_main', serialize($token));
// Fire the login event manually$event = new InteractiveLoginEvent($request, $token);
$this->
get("event_dispatcher")->
dispatch("security.interactive_login", $event);
/** Now the user is authenticated !!!! * Do what you need to do now, like render a view, redirect to route etc.*/}}
完成此操作后, 你已自动在会话中登录了一个用户, 但是未检查该用户的凭据。
定制登录控制器示例假设你正在创建一些自定义登录表单(或覆盖FOSUserBundle的默认登录表单), 并且需要手动验证用户。为此, 第一个控制器示例仅可用于设置会话中的用户, 但是由于我们既不验证用户名也不验证密码, 因此它实际上并未进行身份验证。
在会话中设置用户之前, 我们需要做的第一步是验证他提供的凭据是否正确。为此, 我们需要控制器中的安全编码服务来检查Providen数据的真实性。在此示例中, 我们将以基本逻辑向你展示身份验证过程的工作方式:
<
?phpnamespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class SomeController extends Controller{public function loginAction(Request $request){// This data is most likely to be retrieven from the Request object (from Form)// But to make it easy to understand ...$_username = "batman";
$_password = "batmobil";
// Retrieve the security encoder of symfony$factory = $this->
get('security.encoder_factory');
/// Start retrieve user// Let's retrieve the user by its username:// If you are using FOSUserBundle:$user_manager = $this->
get('fos_user.user_manager');
$user = $user_manager->
findUserByUsername($_username);
// Or by yourself$user = $this->
getDoctrine()->
getManager()->
getRepository("userBundle:User")->
findOneBy(array('username' =>
$_username));
/// End Retrieve user// Check if the user exists !if(!$user){return new Response('Username doesnt exists', Response::HTTP_UNAUTHORIZED, array('Content-type' =>
'application/json'));
}/// Start verification$encoder = $factory->
getEncoder($user);
$salt = $user->
getSalt();
if(!$encoder->
isPasswordValid($user->
getPassword(), $_password, $salt)) {return new Response('Username or Password not valid.', Response::HTTP_UNAUTHORIZED, array('Content-type' =>
'application/json'));
} /// End Verification// The password matches ! then proceed to set the user in session//Handle getting or creating the user entity likely with a posted form// The third parameter "main" can change according to the name of your firewall in security.yml$token = new UsernamePasswordToken($user, null, 'main', $user->
getRoles());
$this->
get('security.token_storage')->
setToken($token);
// If the firewall name is not main, then the set value would be instead:// $this->
get('session')->
set('_security_XXXFIREWALLNAMEXXX', serialize($token));
$this->
get('session')->
set('_security_main', serialize($token));
// Fire the login event manually$event = new InteractiveLoginEvent($request, $token);
$this->
get("event_dispatcher")->
dispatch("security.interactive_login", $event);
/** Now the user is authenticated !!!! * Do what you need to do now, like render a view, redirect to route etc.*/return new Response('Welcome '. $user->
getUsername(), Response::HTTP_OK, array('Content-type' =>
'application/json'));
}}
【如何在Symfony 3上的控制器(带有或不带有FOSUserBundle)中手动验证(登录)用户】编码愉快!
推荐阅读
- 解决方案错误(名称为”yourtable.tablename”的表已存在)
- 如何在WinForms C#中使用LiveCharts库创建地理图表(GeoHeatMap)
- 如何在Microsoft Visual Studio Code中禁用自动补全和智能感知
- 为什么我在android studio中调试时看不到代码()
- 如何在2020年成为一名Android开发人员[关闭]
- Android NDK。从.PVR文件加载ETC1压缩纹理
- google-app-engine部署错误
- Android PopupWindow(白色背景但保留阴影())
- Android WebRTC低成功连接率