我正在开发API,遇到一个刷新令牌问题,此刻我做一个控制器,它接收带有有效令牌的刷新请求,控制器将创建一个新令牌并将最后一个令牌放入黑名单,问题出在这里,这是移动开发人员如何知道令牌的到期时间,我发现随时发送以测试令牌的有效性是不切实际的,因为我使用它的控制器无法刷新过期的令牌 例如:我的令牌有效期为60分钟 如果移动开发人员在这60分钟之前未发出请求,则它将断开与应用程序的连接,因为令牌将过期并且无法刷新,但是如果移动开发人员在60分钟之前发送了刷新令牌的请求,一切将会顺利进行。 我的问题是,我可以生成两个令牌吗?第一个是普通令牌,第二个是在开发人员发送记录时,他收到一个401请求,他使用刷新令牌生成了另外两个令牌,因此他保持连接状态,直到手动断开连接为止>
我的控制器AUthcontroller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Tymon\JWTAuth\Contracts\Providers\Auth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
use Tymon\JWTAuth\Facades\JWTAuth;
use Validator, Hash;
use Illuminate\Support\Facades\Password;
use Carbon\Carbon;
use Config;
use Artisan;
class AuthController extends Controller
{
/**
* API Register
*
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function register( Request $request){
$validator = Validator::make($request -> all(),[
'email' => 'required|string|email|max:255|unique:users',
'username' =>'required',
'tel' => 'required',
'name' => 'required',
'lastname' => 'required',
'adress' => 'required',
'password'=> 'required'
]);
if ($validator -> fails()) {
# code...
return response()->json($validator->errors());
}
$user_data = User::create([
'name' => $request->get('name'),
'email' => $request->get('email'),
'tel' => $request->get('tel'),
'username' => $request->get('username'),
'lastname' => $request->get('lastname'),
'adress' => $request->get('adress'),
'password'=> bcrypt($request->get('password'))
]);
$user = User::first();
$token = JWTAuth::fromUser($user);
return response()->json(['success'=> true,'token'=>compact('token'),'Data'=>$user_data, 'message'=> 'Thanks for signing up']);
}
/**
* API Login, on success return JWT Auth token
*
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
$rules = [
'email' => 'required|email',
'password' => 'required',
];
$validator = Validator::make($credentials, $rules);
if($validator->fails()) {
return response()->json(['success'=> false, 'error'=> $validator->messages()], 401);
}
try {
// attempt to verify the credentials and create a token for the user
$time = isset($request->time) ? $request->time : Config::get('jwt.ttl');
// print_r(Carbon::now()->addSeconds($time)->timestamp);
Config::set('jwt.ttl', $time);
Artisan::call('config:clear');
if (! $token = JWTAuth::attempt($credentials)) {
return response()->json(['success' => false, 'error' => 'We cant find an account with this credentials. Please make sure you entered the right information and you have verified your email address.'], 404);
}
} catch (JWTException $e) {
// something went wrong whilst attempting to encode the token
return response()->json(['success' => false, 'error' => 'Failed to login, please try again.'], 500);
}
// all good so return the token
// $refresh_token = auth('api')->refresh($token)
// $token = Auth::refresh($token);
// $token = JWTAuth::refresh($token);
return response()->json(['success' => true, 'data'=> [ 'token' => $token ]], 200);
}
/**
* Log out
* Invalidate the token, so user cannot use it anymore
* They have to relogin to get a new token
*
* @param Request $request
*/
public function logout(Request $request) {
try {
JWTAuth::invalidate($request->header('Authorization'));
return response()->json(['success' => true, 'message'=> "You have successfully logged out."]);
} catch (JWTException $e) {
// something went wrong whilst attempting to encode the token
return response()->json(['success' => false, 'error' => 'Failed to logout, please try again.'], 500);
}
}
public function token($token = null){
$token = $token ? $token : JWTAuth::getToken();
if(!$token){
throw new BadRequestHtttpException('Token not provided');
}
try{
$token = JWTAuth::refresh($token);
}catch(TokenInvalidException $e){
throw new AccessDeniedHttpException('The token is invalid');
}
return response()->json(['success' => true, 'data' => $token], 200);
}
public function recover(Request $request)
{
$user = User::where('email', $request->email)->first();
if (!$user) {
$error_message = "Your email address was not found.";
return response()->json(['success' => false, 'error' => ['email'=> $error_message]], 401);
}
try {
Password::sendResetLink($request->only('email'), function (Message $message) {
$message->subject('Your Password Reset Link');
});
} catch (\Exception $e) {
//Return with error
$error_message = $e->getMessage();
return response()->json(['success' => false, 'error' => $error_message], 401);
}
return response()->json([
'success' => true, 'data'=> ['message'=> 'A reset email has been sent! Please check your email.']
]);
}
public function changePassword(Request $request)
{
$inputs = $request->only('oldpassword','newpassword');
$rules = [
'oldpassword' => 'required',
'newpassword' => 'required',
];
$validator = Validator::make($inputs, $rules);
if($validator->fails()) {
return response()->json(['success'=> false, 'error'=> $validator->messages()], 401);
}
try {
$authuser = auth()->user();
if (! Hash::check($request->oldpassword, $authuser->password) ){
return response()->json(['success' => false, 'error' => 'You enter wrong old password'], 404);
}
$updated = User::where('email', $authuser->email)->update(['password' => Hash::make($request->newpassword)]);
if($updated){
$gettoken = $this->token($request->header('Authorization'));
$token = $gettoken->original['data'];
}
} catch (JWTException $e) {
// something went wrong whilst attempting to encode the token
return response()->json(['success' => false, 'error' => 'Failed to change password, please try again.'], 500);
}
return response()->json(['success' => true, 'data'=> [ 'message' =>'Password successfully changed',"token"=>$token]], 200);
}
}