简体   繁体   English

如何在有限的时间内对匿名用户进行身份验证/授权?

[英]How to authenticate/authorize anonymous user for a limited time?

Let's say I have an invoice entity. 假设我有一个发票实体。 Invoice belongs to some user ( invoices.user_id ). 发票属于某个用户( invoices.user_id )。

If the user enters myapp.com/invoices/1 he needs to sign in to gain access to his invoice. 如果用户输入myapp.com/invoices/1 ,则需要登录才能访问其发票。 That's pretty normal. 这很正常。

Sometimes invoices.user_id is null (invoice owner doesn't have an account in our system), but we have an invoices.phone_number column. 有时invoices.user_id为空(发票所有者在我们的系统中没有帐户),但我们有一个invoices.phone_number列。

The goal is to create an authentication system based on SMS code verification for users that don't have the account in our system. 目标是为我们系统中没有帐户的用户创建基于SMS代码验证的身份验证系统。 If the user confirms that he indeed owns phone number related to the invoice (code verification) I want to grant him temporary access (15 min) to this invoice details page (and only this page). 如果用户确认他确实拥有与发票相关的电话号码(代码验证),我想授予他临时访问权限(15分钟)到此发票详细信息页面(仅限此页面)。

My first idea was to use a JWT token stored in the session. 我的第一个想法是使用存储在会话中的JWT令牌。

My second idea was to use a custom firewall. 我的第二个想法是使用自定义防火墙。

Is there any better approach? 有没有更好的方法?

Create a kernel.request listener . 创建一个kernel.request 监听器 This way you can act, before anything is executed, and whole application is oblivious to the fact that the user can be logged out any minute. 这样,您可以在执行任何操作之前执行操作,并且整个应用程序无视用户可以在任何时间注销的事实。

Call a "service" which will validate the token. 调用将验证令牌的“服务”。 If the token is not valid, clear authentication status and override the request. 如果令牌无效,请清除身份验证状态并覆盖请求。 For instance, redirect the user to a "you need to pay again" page. 例如,将用户重定向到“您需要再次付款”页面。

This way you don't need to modify any code, execute any voters and so on, your whole application can be protected. 这样您就不需要修改任何代码,执行任何选民等等,您的整个应用程序都可以受到保护。

As for the authentication itself, go for a custom guard , where you can fully control how the authentication process will work. 至于身份验证本身,请选择自定义防护 ,您可以在其中完全控制身份验证过程的工作方式。

You can authenticate a dummy user for 15 minutes using the following action: 您可以使用以下操作对虚拟用户进行15分钟的身份验证:

use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;

public function indexAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();

    /**
     * confirm that the user indeed owns 
     * phone number related to the invoice (code verification)
     */

    //create a user for this task only and fetch it
    $user = $em->getRepository(User::class)->find(1);

    //firewall name used for authentication in security.yml
    $firewall = "main_secured_area";

    $token = new UsernamePasswordToken($user, null, $firewall, $user->getRoles());
    $this->get('security.token_storage')->setToken($token);
    $this->get('session')->set("_security_$firewall", serialize($token));

    //$lifetime takes number of seconds to define session timeout 15min = 900sec
    $this->container->get('session')->migrate($destroy = false, $lifetime = 900);

    //fire the login event manually
    $event = new InteractiveLoginEvent($request, $token);
    $this->get("event_dispatcher")->dispatch("security.interactive_login", $event);

    return $this->render('default/index.html.twig');
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM