草庐IT

php - 拉维尔 5.1/AngularJS : Reset password in Angular view (how to validate CSRF token? )

coder 2024-01-03 原文

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

唯一的问题是,因为我使用的是 Angular View ,所以在显示 reset-password 状态之前,实际上没有任何东西可以验证 token 并确保它不是乱码。我尝试将其添加到 Controller 的顶部:

    if ($stateParams.token != $cookies.get('XSRF_TOKEN')) {
        $state.go('reset');
    }

...这基本上可以查看 token 是否是当前的 CSRF token ,但这不起作用,因为当发送密码重置链接时,CSRF token 已更改或其他...它不再是来自的 token session 。

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

这是我的代码..

应用程序.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 值将 token 传递给它,如果 password_resets 表中不存在该 token ,或者如果该 token 存在且已过期,则返回一些错误。在 Controller 中,我通过重定向处理错误。同样,我不认为这是理想的,因为任何查看源代码的人都可以更改它并删除重定向,因此我必须找到更好的方法来实现它。

不过,现在它仍然有效并且仍然是一个解决方案。

ResetsPasswords.php(添加了获取请求的方法):

public function verifyToken(Request $request)
    {
        $user = DB::table('password_resets')->where('token', $request->only('token'))->first();

        if ($user) {
            if ($user->created_at > Carbon::now()->subHours(2)) {
                return response()->json([
                    'success' => [
                        'message' => 'Token is valid and not expired.'
                    ]
                ], 200);
            } else {
                return response()->json([
                    'error' => [
                        'message' => 'Token is valid but it\'s expired.'
                    ]
                ], 401);
            }
        } else {
            return response()->json([
                'error' => [
                    'message' => 'Token is invalid.'
                ]
            ], 401);
        }
    }

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

编辑:

我认为在 Controller 中检查有效 token 很糟糕,因为它总是至少会在一瞬间加载 View 。我一直在寻找某种中间件,但后来我忘记了我已经在使用 angular-permission包,充当前端中间件。

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

唯一的问题是因为它发生在前端,任何黑客都可以绕过它,但这没关系,因为服务器端代码仍然存在,所以即使他们访问 View ,他们也无法使用他们输入的密码做任何事情,因为 token 仍然无效,必须与特定用户匹配。

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

实现

作用:

        .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'
            })

希望对遇到同样问题的人有所帮助。

关于php - 拉维尔 5.1/AngularJS : Reset password in Angular view (how to validate CSRF token? ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34347726/

有关php - 拉维尔 5.1/AngularJS : Reset password in Angular view (how to validate CSRF token? )的更多相关文章

  1. ruby-on-rails - 获取 ActionController::RoutingError(当尝试使用 AngularJS 将数据发布到 Rails 服务器时,没有路由匹配 [OPTIONS] "/users" - 2

    尝试从我的AngularJS端将数据发布到Rails服务器时出现问题。服务器错误:ActionController::RoutingError(Noroutematches[OPTIONS]"/users"):actionpack(4.1.9)lib/action_dispatch/middleware/debug_exceptions.rb:21:in`call'actionpack(4.1.9)lib/action_dispatch/middleware/show_exceptions.rb:30:in`call'railties(4.1.9)lib/rails/rack/logg

  2. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  3. ruby-on-rails - Rails 还是 Sinatra? PHP程序员入门学习哪个好? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。我使用PHP的时间太长了,对它感到厌倦了。我也想学习一门新语言。我一直在使用Ruby并且喜欢它。我必须在Rails和Sinatra之间做出选择,那么您会推荐哪一个?Sinatra真的不能用来构建复杂的应用程序,它只能用于简单的应用程序吗?

  4. ruby-on-rails - PHP 魔术方法 __call、__get 和 __set 的 Ruby 等价物 - 2

    我很确定Ruby有这些(等同于__call、__get和__set),否则find_by将如何在Rails中工作?也许有人可以举一个简单的例子来说明如何定义与find_by相同的方法?谢谢 最佳答案 简而言之你可以映射__调用带有参数的method_missing调用__设置为方法名称以'='结尾的method_missing调用__获取不带任何参数的method_missing调用__调用PHPclassMethodTest{publicfunction__call($name,$arguments){echo"Callingob

  5. ruby - Lisp - 是否适合网络编程/应用程序(交互式)? ruby 的方式是? php的方式是? - 2

    Lisp是否适合Web编程/应用程序(交互式),就像ruby​​和php一样?需要考虑的事情是:易于使用可部署性难度(尤其是对于编程初学者而言)(编辑)在阅读PaulGraham'sessay之后,我特别提到了CommonLisp.将是我的第一门编程语言。在这方面。这样做合适吗?我听说Clojure的宏功能不如CommonLisp的强大,这就是我尝试学习Clojure的原因。它教授编程并且非常强大。 最佳答案 Lisp是一个语系,而不是单一的语言。为了稍微回答您的问题,是的,存在用于各种Lisp方言的Web框架,例如用于Common

  6. 软件工程毕业设计课题(81)微信小程序毕业设计PHP校园跑腿小程序系统设计与实现 - 2

        项目背景和意义 目的:本课题主要目标是设计并能够实现一个基于微信校园跑腿小程序系统,前台用户使用小程序发布跑腿任何和接跑腿任务,后台管理使用基于PHP+MySql的B/S架构;通过后台管理跑腿的用户、查看跑腿信息和对应订单。意义:手机网络时代,大学生通过手机网购日常用品、外卖外卖、代取快递等已不再是稀奇的事情。此外,不少高校还流行着校园有偿工作,校园跑腿就成了大学生创业服务项目。        因为你在校园里,所以不会有进入的限制。并不是所有的外卖平台都可以随意进入校园,比如小黄和小蓝的双打外卖平台。许多大学禁止送餐进入学校,更不用说送餐进入宿舍了。这一措施使得校园服务市场的竞争相对不

  7. K8s部署PHP项目 - 2

    前言    前端时间PHP项目部署升级需要,需要把Laravel开发的项目部署K8s上,下面以laravel项目为例,讲解采用yaml文件方式部署项目。一、部署步骤1.创建Dockerfile文件Dockerfile是一个用来构建镜像的文本文件,在容器运行时,需要把项目文件和项目运行所必须的组件安装其中。#基础镜像FROMphp:7.4-fpm#时区ARGTZ=Asia/Shanghai#更换容器时区RUNcp"/usr/share/zoneinfo/$TZ"/etc/localtime&&echo"$TZ">/etc/timezone#替换成阿里apt-get源RUNsed-i"s@http

  8. ruby-on-rails - PHP 开发人员学习 Ruby 和 Ruby on Rails - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于StackOverflow来说是偏离主题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,describetheproblem以及迄今为止为解决该问题所做的工作。关闭9年前。Improvethisquestion我对学习Rails很感兴趣已经有一段时间了,我觉得现在正是浸入其中并实际动手实践的好时机。在过去的一周里,我阅读了所有我能找到的关于Ruby和RubyonRails的免费电子书。我刚刚读完RubyEssentials。我也一直在玩htt

  9. ruby-on-rails - Ruby 相当于 PHP 的 ucfirst() 函数 - 2

    在Ruby中(使用Rails,如果相关)将字符串首字母大写的最佳方法是什么?请注意String#capitalize不是我想要的,因为除了将字符串的首字母大写外,此函数还使所有其他字符变为小写(这是我不想要的——我想让它们保持原样):>>"aA".capitalize=>"Aa" 最佳答案 在Rails中你有String#titleize方法:"测试字符串标题化方法".titleize#=>"测试字符串标题化方法" 关于ruby-on-rails-Ruby相当于PHP的ucfirst()

  10. ruby-on-rails - Rails 5.1 使用 RSpec 配置内置系统测试 - 2

    看完RailsConfvideoonActionDispatch::systemTestCase,我很高兴将它整合到我当前的应用程序中。目前我们的测试套件设置使用以下内容:rspecfactory_girlcapybara#功能规范database_cleaner#用于功能规范,主要用于测试jsselenium-webdriver#功能规范capybara-webkit#功能规范很难让配置适用于我们当前的设置,但我们最终成功了,这在很大程度上要归功于AvdiGrimm的一篇文章,标题为:Configuringdatabase_cleanerwithRails,RSpec,Capybar

随机推荐