通过电子邮件而不是SMS发送代码来实现帐户安全:Laravel 5.2

Pan*_*kaj 9 php laravel laravel-5 laravel-5.1 laravel-5.2

当我们第一次登录我们的Gmail帐户或删除缓存和cookie后,我们会在窗口中输入发送到我们移动设备的代码.

我试图通过电子邮件而不是短信来实现这一点.以下是我实现此方法的方法.

我关注此链接: https: //laravel.com/docs/5.2/session

Session table在数据库中创建.我还可以在会话表记录中看到我的浏览器详细信息.我不确定这是否是正确的方法.

Gmail提供了跟踪多个浏览器的功能.这意味着如果我上次从Firefox登录并且这次从Chrome登录,那么我将再次被要求提供代码.展望未来,如果不删除缓存/ Cookie,我将不会要求我填写Chrome和Firefox的代码.

有人可以给我任何链接,解释如何在保存缓存/ cookie时为多个浏览器提供服务吗?这样我就可以发送安全码的电子邮件

jay*_*kar 4

您可以通过发出额外的 cookie(例如 browser_cookie)来记住已经经过身份验证的浏览器来实现此目的。

\n\n

执行:

\n\n

创建下表(browser_management):

\n\n
token (pk)| user_id (fk) | series_identifier\n
Run Code Online (Sandbox Code Playgroud)\n\n

在哪里:

\n\n
    \n
  • token:向用户颁发的令牌的哈希形式(使用 bcrypt 或类似算法)(向用户颁发的令牌本身是从适当大的空间中随机生成的不可猜测的密钥)

  • \n
  • series_identifier:从适当大的空间中随机生成的不可猜测的密钥

  • \n
\n\n

每当用户登录时检查browser_cookie.

\n\n

情况一:用户首次登录。

\n\n

考虑到用户是第一次登录,browser_cookie将不会出现。因此,您将发送一封包含验证码的电子邮件。

\n\n

经过身份验证后,分别为token和生成两个随机数series_identifier。对于 标识的用户,将哈希值token和存储series_identifier在表中。browser_managementuser_id

\n\n

另外,使用和browser_cookie向用户发出。tokenseries_identifier

\n\n

情况2:用户下次重新登录。

\n\n

现在,当同一用户下次登录时,获取并在表中查找带有哈希值的token条目。browser_managementtoken

\n\n

如果找到,检查user_id和是否series_identifier匹配。

\n\n

案例 2.1:匹配的条目:

\n\n

允许用户无需重新验证电子邮件代码即可进入系统。

\n\n

生成另一个令牌并用新的令牌替换token其中的cookie和。table(这将降低会话劫持的风险)。

\n\n

情况 2.2:条目不匹配:

\n\n

按照电子邮件身份验证步骤进行操作,并通知用户有关可能的盗窃行为。(如 gmail 通知新的浏览器登录)。

\n\n

参考:

\n\n\n\n

更新:

\n\n

示例代码:

\n\n

移民:

\n\n
<?php\n\nuse Illuminate\\Database\\Schema\\Blueprint;\nuse Illuminate\\Database\\Migrations\\Migration;\n\nclass browser_management extends Migration\n{\n    /**\n     * Run the migrations.\n     *\n     * @return void\n     */\n    public function up()\n    {\n        Schema::create(\'browser_management\', function (Blueprint $table) {\n            $table->string(\'token\');\n            $table->string(\'user_id\');\n            $table->string(\'series_identifier\');            \n            $table->timestamps();\n            $table->primary(\'token\');\n            $table->foreign(\'user_id\')->references(\'id\')->on(\'users\');\n        });\n    }\n\n    /**\n     * Reverse the migrations.\n     *\n     * @return void\n     */\n    public function down()\n    {\n        Schema::drop(\'users\');\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

中间件:创建一个新的中间件

\n\n
<?php\nnamespace App\\Http\\Middleware;\n\nuse Closure;\nuse Illuminate\\Support\\Facades\\Auth;\nuse Cookies;\n\nclass Email_verification\n{\n    public function handle($request, Closure $next, $guard = null)\n    {\n        //retrieve $token from the user\'s cookie\n        $token = $request->cookie(\'browser_cookie\');\n\n        //check id token is present\n        if($token == null){\n            //if token is not present allow the request to the email_verification\n            return $next($request);\n        }\n        else{\n            //Retrieve the series_identifier issued to the user\n            $series_identifier = Auth::user()\n                                    ->series_identifier(Hash::make($token))\n                                    ->first()\n                                    ->series_identifier;\n\n            //Check if series_identifier matches            \n            if($series_identifier != $request->cookie(\'series_identifier\')){\n                //if series_identifier does not match allow the request to the email_verification\n                return $next($request);\n            }\n        }\n\n       return redirect(\'/dashboard\'); //replace this with your route for home page\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

将中间件的条目添加到kernel.php

\n\n
protected $routeMiddleware = [\n        \'email_verification\' => \\App\\Http\\Middleware\\Email_verification::class,\n        //your middlewares\n];\n
Run Code Online (Sandbox Code Playgroud)\n\n

用户型号:将以下方法添加到您的用户模型中

\n\n
// method to retrieve series_identifier related to token\npublic function series_identifier($token){\n    return $this->hasMany(Browser_management::class)->where(\'token\',$token);\n}\n\n//method to retriev the tokens related to user\npublic function tokens (){\n    return $this->hasMany(Browser_management::class);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

browser_management模型:创建一个模型来表示browser_managements表

\n\n
<?php\n\nnamespace App\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\n\n\nclass Browser_management extends Model\n{\n    protected $primaryKey = \'token\';\n    protected $fillable = array(\'token\',\'series_identifier\');\n\n    public function User(){\n        return $this->hasOne(\'App\\Models\\User\');\n    }    \n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

邮箱验证方法:将以下方法添加到您的 AuthController 中以处理电子邮件验证

\n\n
public function getVerification(Request $request){\n    //Create a random string to represent the token to be sent to user via email. \n    //You can use any string as we are going to hash it in our DB\n    $token = str_random(16);\n\n    //Generate random string to represent series_identifier\n    $series_identifier = str_random(64);\n\n    //Issue cookie to user with the generated series_identifier\n    Cookie::queue(\'series_identifier\', $series_identifier,43200,null,null,true,true);\n\n    //Store the hashed token and series_identifier ini DB\n    Auth::user()->tokens()->create([\'token\'=>Hash::make($token)]);\n\n    //Your code to send an email for authentication\n\n    //return the view with form asking for token\n    return view(\'auth.email_verification\');\n}\n\npublic function postVerification(Request $request){\n    //Retrieve the series_identifier issued to the user in above method\n    $series_identifier = $request->cookie(\'series_identifier\');\n\n    //Retrieve the token associated with the series_identifier\n    $token = Auth::user()\n                ->tokens()\n                ->where(\'series_identifier\',$series_identifier)\n                ->first()\n                ->value(\'token\');\n\n    //Check if the user\'s token\'s hash matches our token entry\n    if(Hash::check($request->token,$token)){\n        // If token matched, issue the cookie with token id in it. Which we can use in future to authenticate the user\n        Cookie::queue(\'token\', $token,43200,null,null,true,true);\n        return redirect(\'dashboard\');\n    }\n\n    //If token did not match, redirect user bak to the form with error\n    return redirect()->back()\n                ->with(\'msg\',\'Tokens did not match\');\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

路线:添加这些路由以处理电子邮件验证请求。我们还将向其中添加 email_verification 中间件。

\n\n
Route::get(\'/auth/email_verification\',`AuthController@getVerification\')->middleware(\'email_verification\');\nRoute::post(\'/auth/email_verification\',`AuthController@postVerification\')->middleware(\'email_verification\');<br/>\n
Run Code Online (Sandbox Code Playgroud)\n\n

更新2:

\n\n

关于 gmail 的流程..
\n我按照以下步骤操作:
\n1)登录 gmail,然后进行两步验证。
\n2)注销
\n3)清除缓存链接
\n4)重新登录

\n\n

当我再次登录时,清除缓存后,它没有要求我进行两步验证。

\n\n

不过,如果您清除 cookie,它会要求进行两步验证。\n原因:
\n识别用户的所有用户数据(此处token)都存储在 cookie 中。如果清除cookie,服务器将没有机制来识别用户。

\n\n

更新3:

\n\n

Gmail 要求两步验证:
\n首先,Gmail 或任何其他网站都不会收到有关清除缓存的通知
\n如所给出的如下所示:

\n\n
\n

缓存只不过是硬盘上的一个位置,浏览器在其中保存曾经下载过的内容,以备再次需要时使用。

\n
\n\n

现在,cookie是服务器发出的用于存储用户相关信息的小文本文件。如所给出的这里给出的

\n\n
\n

Cookie 的主要用途是识别用户身份并可能为您准备自定义网页或保存网站登录信息。

\n
\n\n

因此,基本上当您清除浏览器中的cookie时,网络服务器将不会获取任何用户数据。因此,用户将被视为访客并受到相应的待遇。

\n