Php Laravel 5.1/AngularJS:在角度视图中重置密码(如何验证CSRF令牌?)

Php Laravel 5.1/AngularJS:在角度视图中重置密码(如何验证CSRF令牌?),php,angularjs,laravel,laravel-5,csrf,Php,Angularjs,Laravel,Laravel 5,Csrf,我设法调整了默认的Laravel auth,使它可以作为AngularJS的API使用,到目前为止一切都很好。可以转到/reset并输入一封电子邮件,然后收到一封带有密码重置链接的电子邮件,该链接指向/reset/{token},如果您没有收到任何验证错误,您的密码将成功更改 唯一的问题是,因为我使用的是角度视图,所以在显示重置密码状态之前,没有任何东西验证令牌并确保它不仅仅是胡言乱语。我尝试将此添加到控制器的顶部: if ($stateParams.token != $cookies.

我设法调整了默认的Laravel auth,使它可以作为AngularJS的API使用,到目前为止一切都很好。可以转到/reset并输入一封电子邮件,然后收到一封带有密码重置链接的电子邮件,该链接指向/reset/{token},如果您没有收到任何验证错误,您的密码将成功更改

唯一的问题是,因为我使用的是角度视图,所以在显示
重置密码
状态之前,没有任何东西验证令牌并确保它不仅仅是胡言乱语。我尝试将此添加到控制器的顶部:

    if ($stateParams.token != $cookies.get('XSRF_TOKEN')) {
        $state.go('reset');
    }
…这基本上可以看出令牌是否是当前的CSRF令牌,但这不起作用,因为当发送密码重置链接时,CSRF令牌会发生更改或其他情况。。。它不再是会话中的令牌

有人知道我该怎么做吗?如果在“/reset/:token”的url中输入的令牌无效,我只想重定向用户

这是我的密码

App.js:

        .state('reset', {
            url: '/reset',
            data: {
                permissions: {
                    except: ['isLoggedIn'],
                    redirectTo: 'user.dashboard'
                }
            },
            templateUrl: 'views/auth/forgot-password.html',
            controller: 'ForgotPasswordController as forgot'
        })
        .state('reset-password', {
            url: '/reset/:token',
            data: {
                permissions: {
                    except: ['isLoggedIn'],
                    redirectTo: 'user.dashboard'
                }
            },
            templateUrl: 'views/auth/reset-password.html',
            controller: 'ResetPasswordController as reset'
        })
这在ResetsPassword.php中的ResetsPassword特性中。大多数已设置,但我删除/更改了很多以用作API:

     /**
     * Send a reset link to the given user.
     */
    public function postEmail(EmailRequest $request)
    {
        $response = Password::sendResetLink($request->only('email'), function (Message $message) {
            $message->subject($this->getEmailSubject());
        });

        switch ($response) {
            case Password::RESET_LINK_SENT:
                return;

            case Password::INVALID_USER:
                return response()->json([
                    'denied' => 'We couldn\'t find your account with that information.'
                ], 404);
        }
    }

    /**
     * Get the e-mail subject line to be used for the reset link email.
     */
    protected function getEmailSubject()
    {
        return property_exists($this, 'subject') ? $this->subject : 'Your Password Reset Link';
    }

    /**
     * Reset the given user's password.
     */
    public function postReset(ResetRequest $request)
    {
        $credentials = $request->only(
            'password', 'password_confirmation', 'token'
        );

        $response = Password::reset($credentials, function ($user, $password) {
            $this->resetPassword($user, $password);
        });

        switch ($response) {
            case Password::PASSWORD_RESET:
                return;

            default:
                return response()->json([
                    'error' => [
                        'message' => 'Could not reset password'
                    ]
                ], 400);
        }
    }

    /**
     * Reset the given user's password.
     */
    protected function resetPassword($user, $password)
    {
        $user->password = bcrypt($password);

        $user->save();
    }
我明白了

对于任何有类似问题的人。。。下面是我如何解决它的(以后可能会使它变得更好,但现在它起作用了)

我为API添加了另一个url,它是
reset/password
,它接受GET请求。我根据
$stateParams
值将令牌传递给它,如果
password\u resets
表中不存在该令牌,或者如果该令牌确实存在并且已过期,则返回一些错误。在控制器中,我通过重定向处理错误。同样,我认为这并不理想,因为任何查看源代码的人都可以对其进行更改并删除重定向,因此我必须找到更好的方法来实现这一点

不过,就目前而言,它仍然有效,而且是一个解决方案

ResetsPasswords.php(为get请求添加了一个方法):

在我的resetPasswordController.js中,我只需检查响应是否返回“成功”或任何“错误”响应,如果是“错误”响应,我只需执行类似于
$state.go('reset')
的操作,这会将他们重定向回“忘记密码”表单,在那里他们输入电子邮件以获得重置密码链接

编辑:

我认为在控制器中检查有效令牌是错误的,因为它总是至少在一瞬间加载视图。我在寻找某种中间件,但后来我忘了我已经在使用这个包,它可以充当前端中间件

我定义了一个角色
isTokenValid
,并将其设置为自动调用我拥有的authService中的函数,并根据令牌的有效性从我的API获取响应。如果成功,角色允许用户进入状态。否则它将重定向到
重置
状态。这将阻止在瞬间显示视图。行为与Laravel中间件非常相似

唯一的问题是,由于它发生在前端,任何黑客都可以绕过它,但这没关系,因为服务器端代码仍然存在,因此即使他们访问视图,他们也无法使用输入的密码执行任何操作,因为令牌仍然无效,并且必须与特定用户匹配

另一个改进是找到一种即使没有前端中间件实现也不允许该视图的方法。如果我找到一个方法,也许我会再次更新这个

实施

作用:

        .defineRole('isTokenValid', function(stateParams) {
            var token = stateParams.token;
            var deferred = $q.defer();

            authService.verifyToken(token)
                .then(function(res) {
                    if (res.success) {
                        deferred.resolve();
                    }
                }, function(res) {
                    if (res.error) {
                        deferred.reject();
                    }
                });

            return deferred.promise;
        });
国家:

            .state('reset-password', {
                url: '/reset/:token',
                data: {
                    permissions: {
                        only: ['isTokenValid'],
                        redirectTo: 'reset'
                    }
                },
                templateUrl: 'views/auth/reset-password.html',
                controller: 'ResetPasswordController as reset'
            })

希望它能帮助任何有同样问题的人。

这是一个有用的问题,对于任何使用Laravel和Angular开发的人来说都是一个很好的说明。谢谢你的发帖。
            .state('reset-password', {
                url: '/reset/:token',
                data: {
                    permissions: {
                        only: ['isTokenValid'],
                        redirectTo: 'reset'
                    }
                },
                templateUrl: 'views/auth/reset-password.html',
                controller: 'ResetPasswordController as reset'
            })