Commit 30c98fd9 authored by Viral Solani's avatar Viral Solani

Change JWT configuration (WIP)

parent b788def5
......@@ -16,6 +16,7 @@ Thumbs.db
_ide_helper.php
composer.phar
error.log
access.log
Todo.rtf
.vagrant
/.vagrant
......
This diff is collapsed.
......@@ -4,7 +4,7 @@ namespace App\Http\Controllers\Api\V1;
use App\Models\Access\User\User;
use Illuminate\Http\Request;
use JWTAuth;
use Illuminate\Support\Facades\Auth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Validator;
......@@ -20,8 +20,8 @@ class AuthController extends APIController
public function login(Request $request)
{
$validation = Validator::make($request->all(), [
'email' => 'required|email',
'password' => 'required|min:4',
'email' => 'required|email',
'password' => 'required|min:4',
]);
if ($validation->fails()) {
......@@ -31,17 +31,24 @@ class AuthController extends APIController
$credentials = $request->only(['email', 'password']);
try {
if (!$token = JWTAuth::attempt($credentials)) {
if (!$token = auth('api')->attempt($credentials)) {
return $this->throwValidation(trans('api.messages.login.failed'));
}
} catch (JWTException $e) {
return $this->respondInternalError($e->getMessage());
}
return $this->respond([
'message' => trans('api.messages.login.success'),
'token' => $token,
]);
return $this->respondWithToken($token);
}
/**
* Get the authenticated User.
*
* @return \Illuminate\Http\JsonResponse
*/
public function me()
{
return response()->json($this->guard()->user());
}
/**
......@@ -51,19 +58,9 @@ class AuthController extends APIController
*/
public function logout()
{
try {
$token = JWTAuth::getToken();
$this->guard()->logout();
if ($token) {
JWTAuth::invalidate($token);
}
} catch (JWTException $e) {
return $this->respondInternalError($e->getMessage());
}
return $this->respond([
'message' => trans('api.messages.logout.success'),
]);
return response()->json(['message' => 'Successfully logged out']);
}
/**
......@@ -73,21 +70,79 @@ class AuthController extends APIController
*/
public function refresh()
{
$token = JWTAuth::getToken();
if (!$token) {
$this->respondUnauthorized(trans('api.messages.refresh.token.not_provided'));
}
try {
$refreshedToken = JWTAuth::refresh($token);
} catch (JWTException $e) {
return $this->respondInternalError($e->getMessage());
}
return $this->respondWithToken($this->guard()->refresh());
}
return $this->respond([
'status' => trans('api.messages.refresh.status'),
'token' => $refreshedToken,
/**
* Get the token array structure.
*
* @param string $token
*
* @return \Illuminate\Http\JsonResponse
*/
protected function respondWithToken($token)
{
return response()->json([
'access_token' => $token,
// 'token_type' => 'bearer',
// 'expires_in' => $this->guard()->factory()->getTTL() * 60
]);
}
/**
* Get the guard to be used during authentication.
*
* @return \Illuminate\Contracts\Auth\Guard
*/
public function guard()
{
return Auth::guard('api');
}
/*
* Log the user out (Invalidate the token).
*
* @return \Illuminate\Http\JsonResponse
*/
// public function logout()
// {
// try {
// $token = JWTAuth::getToken();
// if ($token) {
// JWTAuth::invalidate($token);
// }
// } catch (JWTException $e) {
// return $this->respondInternalError($e->getMessage());
// }
// return $this->respond([
// 'message' => trans('api.messages.logout.success'),
// ]);
// }
/*
* Refresh a token.
*
* @return \Illuminate\Http\JsonResponse
*/
// public function refresh()
// {
// $token = JWTAuth::getToken();
// if (!$token) {
// $this->respondUnauthorized(trans('api.messages.refresh.token.not_provided'));
// }
// try {
// $refreshedToken = JWTAuth::refresh($token);
// } catch (JWTException $e) {
// return $this->respondInternalError($e->getMessage());
// }
// return $this->respond([
// 'status' => trans('api.messages.refresh.status'),
// 'token' => $refreshedToken,
// ]);
// }
}
......@@ -63,20 +63,20 @@ class Kernel extends HttpKernel
* @var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'timeout' => \App\Http\Middleware\SessionTimeout::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'timeout' => \App\Http\Middleware\SessionTimeout::class,
/*
* Access Middleware
*/
'access.routeNeedsRole' => \App\Http\Middleware\RouteNeedsRole::class,
'access.routeNeedsRole' => \App\Http\Middleware\RouteNeedsRole::class,
'access.routeNeedsPermission' => \App\Http\Middleware\RouteNeedsPermission::class,
'jwt.auth' => GetUserFromToken::class,
'jwt.refresh' => RefreshToken::class,
// 'jwt.auth' => GetUserFromToken::class,
// 'jwt.refresh' => RefreshToken::class,
];
}
......@@ -78,6 +78,18 @@ class User extends Authenticatable implements JWTSubject
return $this->getKey();
}
/**
* Set password attribute.
*
* @param [string] $password
*/
public function setPasswordAttribute($password)
{
if (!empty($password)) {
$this->attributes['password'] = bcrypt($password);
}
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
......@@ -86,17 +98,17 @@ class User extends Authenticatable implements JWTSubject
public function getJWTCustomClaims()
{
return [
'id' => $this->id,
'first_name' => $this->first_name,
'last_name' => $this->last_name,
'email' => $this->email,
'picture' => $this->getPicture(),
'confirmed' => $this->confirmed,
'role' => optional($this->roles()->first())->name,
'permissions' => $this->permissions()->get(),
'status' => $this->status,
'created_at' => $this->created_at->toIso8601String(),
'updated_at' => $this->updated_at->toIso8601String(),
'id' => $this->id,
'first_name' => $this->first_name,
'last_name' => $this->last_name,
'email' => $this->email,
'picture' => $this->getPicture(),
'confirmed' => $this->confirmed,
'role' => optional($this->roles()->first())->name,
'permissions' => $this->permissions()->get(),
'status' => $this->status,
'created_at' => $this->created_at->toIso8601String(),
'updated_at' => $this->updated_at->toIso8601String(),
];
}
}
......@@ -9,8 +9,9 @@
* file that was distributed with this source code.
*/
return [
use Tymon\JWTAuth\Claims;
return [
/*
|--------------------------------------------------------------------------
| JWT Authentication Secret
......@@ -45,7 +46,6 @@ return [
*/
'keys' => [
/*
|--------------------------------------------------------------------------
| Public Key
......@@ -82,7 +82,6 @@ return [
*/
'passphrase' => env('JWT_PASSPHRASE'),
],
/*
......@@ -91,7 +90,7 @@ return [
|--------------------------------------------------------------------------
|
| Specify the length of time (in minutes) that the token will be valid for.
| Defaults to 1 hour.
| Defaults to 30 minutes.
|
| You can also set this to null, to yield a never expiring token.
| Some people may want this behaviour for e.g. a mobile app.
......@@ -100,26 +99,21 @@ return [
|
*/
'ttl' => env('JWT_TTL', 60),
'ttl' => env('JWT_TTL', 30),
/*
|--------------------------------------------------------------------------
| Refresh time to live
| Max refresh period
|--------------------------------------------------------------------------
|
| Specify the length of time (in minutes) that the token can be refreshed
| within. I.E. The user can refresh their token within a 2 week window of
| the original token being created until they must re-authenticate.
| Defaults to 2 weeks.
| Specify the length of time (in minutes) that the token will be
| refreshable for.
|
| You can also set this to null, to yield an infinite refresh time.
| Some may want this instead of never expiring tokens for e.g. a mobile app.
| This is not particularly recommended, so make sure you have appropriate
| systems in place to revoke the token if necessary.
| Defaults to null, which will allow tokens to be refreshable forever.
|
*/
'refresh_ttl' => env('JWT_REFRESH_TTL', 20160),
'max_refresh_period' => env('JWT_MAX_REFRESH_PERIOD'),
/*
|--------------------------------------------------------------------------
......@@ -128,8 +122,11 @@ return [
|
| Specify the hashing algorithm that will be used to sign the token.
|
| See here: https://github.com/namshi/jose/tree/master/src/Namshi/JOSE/Signer/OpenSSL
| for possible values.
| Possible values:
|
| 'HS256', 'HS384', 'HS512',
| 'RS256', 'RS384', 'RS512',
| 'ES256', 'ES384', 'ES512'
|
*/
......@@ -147,31 +144,48 @@ return [
*/
'required_claims' => [
'iss',
'iat',
'exp',
'nbf',
'sub',
'jti',
Claims\Issuer::NAME,
Claims\IssuedAt::NAME,
Claims\Expiration::NAME,
Claims\Subject::NAME,
Claims\JwtId::NAME,
],
/*
|--------------------------------------------------------------------------
| Persistent Claims
| Lock Subject
|--------------------------------------------------------------------------
|
| Specify the claim keys to be persisted when refreshing a token.
| `sub` and `iat` will automatically be persisted, in
| addition to the these claims.
| This will determine whether a `prv` claim is automatically added to
| the token. The purpose of this is to ensure that if you have multiple
| authentication models e.g. `App\User` & `App\OtherPerson`, then we
| should prevent one authentication request from impersonating another,
| if 2 tokens happen to have the same id across the 2 different models.
|
| Note: If a claim does not exist then it will be ignored.
| Under specific circumstances, you may want to disable this behaviour
| e.g. if you only have one authentication model, then you would save
| a little on token size.
|
*/
'persistent_claims' => [
// 'foo',
// 'bar',
],
'lock_subject' => true,
/*
|--------------------------------------------------------------------------
| Leeway
|--------------------------------------------------------------------------
|
| This property gives the jwt timestamp claims some "leeway".
| Meaning that if you have any unavoidable slight clock skew on
| any of your servers then this will afford you some level of cushioning.
|
| This applies to the claims `iat`, `nbf` and `exp`.
|
| Specify in seconds - only if you know you need it.
|
*/
'leeway' => env('JWT_LEEWAY', 0),
/*
|--------------------------------------------------------------------------
......@@ -212,11 +226,11 @@ return [
| see https://laravel.com/docs/master/responses#cookies-and-encryption
| for details.
|
| Set it to false if you don't want to decrypt cookies.
| Set it to true if you want to decrypt cookies.
|
*/
'decrypt_cookies' => true,
'decrypt_cookies' => false,
/*
|--------------------------------------------------------------------------
......@@ -228,7 +242,6 @@ return [
*/
'providers' => [
/*
|--------------------------------------------------------------------------
| JWT Provider
......@@ -238,18 +251,7 @@ return [
|
*/
'jwt' => Tymon\JWTAuth\Providers\JWT\Namshi::class,
/*
|--------------------------------------------------------------------------
| Authentication Provider
|--------------------------------------------------------------------------
|
| Specify the provider that is used to authenticate users.
|
*/
'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,
'jwt' => Tymon\JWTAuth\Providers\JWT\Lcobucci::class,
/*
|--------------------------------------------------------------------------
......@@ -261,7 +263,5 @@ return [
*/
'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,
],
];
......@@ -2,7 +2,6 @@
namespace Tests\Feature\Api\V1;
use Illuminate\Support\Facades\Auth;
use Tests\TestCase;
class LoginTest extends TestCase
......@@ -11,9 +10,9 @@ class LoginTest extends TestCase
public function users_can_login_through_api()
{
$res = $this->json('POST', '/api/v1/auth/login', [
'email' => $this->user->email,
'password' => '1234',
])
'email' => $this->user->email,
'password' => '1234',
])
->assertStatus(200)
->assertJsonStructure([
'message',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment