我设法调整默认的Laravel auth,以便它可以作为我的AngularJS的API,到目前为止一切正常.可以转到/重置并输入电子邮件,并收到一封带有密码重置链接的电子邮件,该链接转至/ reset/{token},如果您没有收到任何验证错误,您的密码将成功更改.
唯一的问题是因为我使用的是Angular视图,所以没有任何验证令牌的确实存在,并确保在显示reset-password
状态之前不仅仅是乱码.我尝试将其添加到控制器的顶部:
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(); }
Lansana Cama.. 5
想出这个.
对于任何有类似问题的人......这就是我解决它的方法(以后可能会更好,但现在它可以工作).
我添加了另一个API的URL reset/password
,它需要一个GET请求.我根据$stateParams
值传递令牌,如果该令牌不存在于password_resets
表中,或者该令牌确实存在且已过期,则返回一些错误.在控制器中,我通过重定向处理错误.我不认为这是理想的,因为任何查看源代码的人都可以更改它并删除重定向,因此我必须找到更好的方法来实现它.
但同样,现在它仍然有效,它仍然是一个解决方案.
ResetsPasswords.php(为get请求添加了一个方法):
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是否返回'success'或任何'error'响应,如果是'错误'响应,我会做一些像$state.go('reset')
将其重定向回"忘记密码"的事情.表格,他们输入他们的电子邮件,以获得重置密码链接.
编辑:
我认为在控制器中检查有效令牌是不好的,因为它总是会加载视图至少一瞬间.我正在寻找某种中间件,但后来我忘记了我已经在使用angular-permission软件包,它有点像前端中间件.
我定义了一个角色isTokenValid
并进行了设置,以便它自动调用我拥有的authService中的函数,并根据令牌的有效性从我的API获取响应.如果成功,该角色允许用户进入该状态.否则它会重定向到该reset
状态.这可以防止显示分秒的视图.与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' })
希望它可以帮助任何有同样问题的人.
想出这个.
对于任何有类似问题的人......这就是我解决它的方法(以后可能会更好,但现在它可以工作).
我添加了另一个API的URL reset/password
,它需要一个GET请求.我根据$stateParams
值传递令牌,如果该令牌不存在于password_resets
表中,或者该令牌确实存在且已过期,则返回一些错误.在控制器中,我通过重定向处理错误.我不认为这是理想的,因为任何查看源代码的人都可以更改它并删除重定向,因此我必须找到更好的方法来实现它.
但同样,现在它仍然有效,它仍然是一个解决方案.
ResetsPasswords.php(为get请求添加了一个方法):
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是否返回'success'或任何'error'响应,如果是'错误'响应,我会做一些像$state.go('reset')
将其重定向回"忘记密码"的事情.表格,他们输入他们的电子邮件,以获得重置密码链接.
编辑:
我认为在控制器中检查有效令牌是不好的,因为它总是会加载视图至少一瞬间.我正在寻找某种中间件,但后来我忘记了我已经在使用angular-permission软件包,它有点像前端中间件.
我定义了一个角色isTokenValid
并进行了设置,以便它自动调用我拥有的authService中的函数,并根据令牌的有效性从我的API获取响应.如果成功,该角色允许用户进入该状态.否则它会重定向到该reset
状态.这可以防止显示分秒的视图.与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' })
希望它可以帮助任何有同样问题的人.