Laravel 5.6 authentication with JWT and ADLDAP - php

I have both my ldap server set up (with adldap2/adldap2-laravel) and my JWT set up (with tymon/jwt-auth) for a SPA built with Vue/Vuetify and Laravel api backend. The JWT is all set up to the point where if I leave my provider as eloquent, I can get a successful login attempt with my eloquent users:
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
]
],
As soon as I change the driver to adldap and attempt a username/password that is known to be valid in our ldap system, I am stuck on an unauthorized error. Does anyone have any advice or resources to marry these two? I know that there are a lot of differences with laravel/passport sessions and JWT, but I'm not seeing a simple solution. Here is my AuthController:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class AuthController extends Controller
{
use AuthenticatesUsers;
/**
* Create a new AuthController instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('jwt', ['except' => ['login']]);
}
public function login()
{
$credentials = request(['username', 'password']);
if (! $token = auth()->attempt($credentials)) {
return response()->json(['error' => 'Unauthorized'], 401);
}
return $this->respondWithToken($token);
}
public function me()
{
return response()->json(auth()->user());
}
public function logout()
{
auth()->logout();
return response()->json(['message' => 'Successfully logged out']);
}
public function refresh()
{
return $this->respondWithToken(auth()->refresh());
}
protected function respondWithToken($token)
{
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth()->factory()->getTTL() * 60,
'user' => auth()->user()->name
]);
}
}

Related

Laravel 8 and JWT Auth have SSL Connection error when call API's

I am new to using JWT on Laravel, and I am developing a personal management application.
I have configured the environment with Laravel 8 for the backend, React for the frontend and I manage the authentication with JTW Token.
I then set up the Laravel project following this tutorial.
tutorial link
So I'm testing the APIs with Insomnia before moving on to implementing and using them in the React application.
But I have the following problem, when I call (from Insomnia) the POST logout API: https://localhost:8000/api/logout I get the error message "Error: SSL connect error".
I have no idea what it comes from, also because the other APIs work correctly, and the custom ones are able to correctly retrieve data from the DB.
Do you have any suggestions or advice?
-my code:
JWT Controller
<?php
namespace App\Http\Controllers;
use Auth;
use Validator;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
class JWTController extends Controller
{
/**
* Create a new AuthController instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login', 'register']]);
}
/**
* Register user.
*
* #return \Illuminate\Http\JsonResponse
*/
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required|string|min:2|max:100',
'email' => 'required|string|email|max:100|unique:users',
'password' => 'required|string|confirmed|min:6',
]);
if($validator->fails()) {
return response()->json($validator->errors(), 400);
}
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password)
]);
return response()->json([
'message' => 'User successfully registered',
'user' => $user
], 201);
}
/**
* login user
*
* #return \Illuminate\Http\JsonResponse
*/
public function login(Request $request)
{
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'password' => 'required|string|min:6',
]);
if ($validator->fails()) {
return response()->json($validator->errors(), 422);
}
if (!$token = auth()->attempt($validator->validated())) {
return response()->json(['error' => 'Unauthorized'], 401);
}
return $this->respondWithToken($token);
}
/**
* Logout user
*
* #return \Illuminate\Http\JsonResponse
*/
public function logout()
{
auth()->logout(true);
return response()->json(['message' => 'User successfully logged out.']);
}
/**
* Refresh token.
*
* #return \Illuminate\Http\JsonResponse
*/
public function refresh()
{
return $this->respondWithToken(auth()->refresh());
}
/**
* Get user profile.
*
* #return \Illuminate\Http\JsonResponse
*/
public function profile()
{
return response()->json(auth()->user());
}
/**
* 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' => auth()->factory()->getTTL() * 60
]);
}
}
api.php
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\JWTController;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::group(['middleware' => ['api', 'cors']], function($router) {
Route::post('/register', [JWTController::class, 'register']);
Route::post('/login', [JWTController::class, 'login']);
Route::post('/logout', [JWTController::class, 'logout']);
Route::post('/refresh', [JWTController::class, 'refresh']);
Route::post('/profile', [JWTController::class, 'profile']);
});
It will fix it by changing HTTPS to HTTP API: https://localhost:8000/api/logout to http://localhost:8000/api/logout
localhost does not support HTTPS

Cannot create access token with Laravel passport?

I tried implementing Passport to my project and upon Login attempt, I cannot return the access token.
This is my User model
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasFactory, Notifiable, HasApiTokens;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
And this is the Login controller, the login works, if i try to just return the authenticated user it works, but createToken() method is not recognized for some reason
<?php
namespace App\Http\Controllers\Api\V1;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
class LoginController extends Controller
{
public function Login(Request $request){
$login = $request->validate([
'email' => 'required|string|max:255',
'password' => 'required|string|max:255',
]);
//Check wether the login credentials are valid
if( !Auth::attempt($login)){
return response(['message' => 'Invalid login credentials'], 401);
}
else{
return(Auth::user()->createToken());
}
}
}
And this is the config file for the auth.php, I added the api driver and provider as the documentation suggested
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
The reason behind this is that you cannot pass any value to the access token. Do the below code :
$token = auth()->user()->createToken('API Token')->accessToken;
return response(['user' => auth()->user(), 'token' => $token]);
Try out this.
public function Login(Request $request){
$login = $request->validate([
'email' => 'required|string|max:255',
'password' => 'required|string|max:255',
]);
//Check wether the login credentials are valid
if( !Auth::attempt($login)){
return response(['message' => 'Invalid login credentials'], 401);
}
else{
$token = Auth::user()->createToken('TutsForWeb')->accessToken
return $token;
}
}
refer this doc
https://laravel.com/docs/8.x/passport#managing-personal-access-tokens

Laravel Sanctum tokenCan method on User model returns false despite correct ability

I'm using Laravel Sanctum in my Laravel 8 project, I'm building a controller which will allow other Laravel projects to authenticate and check the abilities of a token, to do this I'm finding a token using the findToken method, grabbing the tokenable_id (this is the user id) and then looking up this user based on the User model.
I'm then storing this in a variable and checking the abilities with tokenCan but it's always returning false despite my token having the correct abilities, what am I missing from this method?
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Laravel\Sanctum\PersonalAccessToken;
use App\Models\User;
class HubController extends Controller
{
/**
* Instantiate a new AccountController instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('throttle:30,1');
}
/**
* Handle the incoming request.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function __invoke(Request $request)
{
$validator = Validator::make($request->all(), [
'token' => 'required|string',
'ability' => 'required|string'
]);
if ($validator->fails()) {
return response()->json([
'message' => "It looks like you've missed something.",
'errors' => $validator->messages()
], 400);
}
$token = PersonalAccessToken::findToken($request->input('token'));
if (!$token) {
return response()->json([
'message' => "Token not found or is invalid"
], 404);
}
$user = User::find($token->tokenable_id);
if (!$user) {
return response()->json([
'message' => "User not found or is invalid"
], 404);
}
// $user->tokenCan('reports:view') always returning false
return response()->json([
'token' => $user->tokenCan('reports:view'),
'message' => "You don't have the correct permissions to perform this action."
], 401);
return response()->json([
'user' => $user
], 200);
}
}
you can get $user with $request->user().
or use $request->user()->tokenCan('reports:view')

Laravel - Auth, route is not logged

I've a problem when route call a method of Controller after login successfull.
In the new method user seems to be not logged.
I can't understand why.
Steps are: Log-in with
Route::post('login', 'UserController#login')->name('login');
and than check if user is logged with:
Route::get('check-login', 'UserController#checklogged');
Controller is this one:
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Faker\Generator as Faker;
class UserController extends Controller
{
// regole per FormValidator
protected $rulesLogin = [
'email' => 'bail|required|email',
'password' => 'required',
];
// Effettuo il login
/**
* Method: POST
* #Parameters: email, password
* return: Authenticated User.
*/
public function login(Request $request)
{
//dd($request->all());
$validator = Validator::make($request->all(),$this->rulesLogin);
// login fallito
if ($validator->failed()) {
return response([
'status' => 'ko',
'message' => $validator->errors()->first(),
], 422);
}
// login errato
if (!Auth::attempt([
'email' => $request->email,
'password' => $request->password,
'status' => ['active'],
])) {
return response(
[
'status' => 'ko',
'message' => 'Invalid email or password',
], 422);
}
return (Auth::user());
}
public function checklogged()
{
return dd(Auth::id());
}
checklogged() return always false. I expect it return a user logged Id
I think the problem is u havent used web midlleware in route.If you are following HMVC pattern make sure to use web middleware like this.
Route::group([
'middleware' => ['web'],
], function () {
});
or please check your RouteServiceProvider.php file weather it has web middleware in mapWebRoutes() function
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
problem was middleware as guest.
Route::post('login', 'UserController#login')->name('login')->middleware('guest');
Try this sintaxe:
public function checklogged()
{
return dd(Auth::user()->id);
}

Laravel doesn't authenticate users after migrating jwt from 5.4 to 1.0.x

Previously we used laravel 5.4 just fine with jwt-auth 0.5.4, we overrode BaseMiddleware.php and we added our own logic to app/Http/Middleware/TokenAuthentication.php (the purpose was to separate authorization from authentication):
// The purpose of this middleware is to check the oauth token send in the autherization header.
// If the user exists, it is attached to the rest of the requests.
// This middleware does not check authorization, that is done in TokenAuthorization.php
// see https://scotch.io/tutorials/role-based-authentication-in-laravel-with-jwt
class TokenAuthentication extends BaseMiddleware
{
public function handle($request, Closure $next)
{
if (! $token = $this->auth->setRequest($request)->getToken()) {
return $next($request);
}
try {
$token = $this->handleToken($token);
$user = $this->auth->authenticate($token);
} catch (TokenExpiredException $e) {
return $next($request);
} catch (JWTException $e) {
return $next($request);
}
$this->events->fire('tymon.jwt.valid', $user);
return $next($request);
}
private function handleToken($token)
{
$token = str_replace(['{', '}'], '', $token);
$token = str_replace(' ', '', $token);
return $token;
}
}
with our (relevant) middlewares listed in app/Http/Kernel.php like so:
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
* #var array
*/
protected $middleware = [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Session\Middleware\StartSession::class,
..
\App\Http\Middleware\TokenAuthentication::class,
..
];
}
/**
* The application's route middleware.
* #var array
*/
protected $routeMiddleware = [
'auth.jwt' => \App\Http\Middleware\TokenAuthorization::class,
];
My user.php looked like this:.
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
class User extends Model implements AuthenticatableContract, AuthorizableContract {
use Authenticatable, CsvCustomCollection,
SoftDeletes, Notifiable, EntrustUserTrait;
This all worked perfectly, but when we decided to switch to tymon 1.0.0-rc,
The problem with the new library is that this Auth::Check() keeps on failing in app/Http/Middleware/TokenAuthorization.php:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class TokenAuthorization
{
public function handle($request, Closure $next, $roles = '', $permissions = '', $validateAll = false)
{
if (Auth::check() === false) { <--- always fails here
return response()->error('Failed to authenticate because of bad credentials or an invalid authorization header :)', 401);
}
..
return $next($request);
}
}
One thing we had to change in our app/Http/Middleware/TokenAuthentication.php above is commenting this part out
$this->events->fire('tymon.jwt.valid', $user);
since the new BaseMiddleware of Tymon 1.0 has no concept of events per se.
here is the relevant part of our config/auth.php:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
],
Now my userphp looks like so
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable implements JWTSubject
{
use CsvCustomCollection,
SoftDeletes, Notifiable, EntrustUserTrait;
What went wrong?

Categories