I'm trying to secure the image urls on my react website with Laravel, but it doesn't collect the token from the auth when I log in. I have tried with jwt middlewere, json-middlewere and it has not worked.
<?php
namespace App\Http\Middleware;
use Closure;
class JsonMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$request->headers->set('Accept', 'application/json');
return $next($request);
}
}
<?php
namespace App\Http\Middleware;
use Closure;
use JWTAuth;
use Exception;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
class JwtMiddleware extends BaseMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
try {
$user = JWTAuth::parseToken()->authenticate();
} catch (Exception $e) {
if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException){
return response()->json(['status' => 'Token is Invalid']);
}else if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException){
return response()->json(['status' => 'Token is Expired']);
}else{
return response()->json(['status' => 'Authorization Token not found']);
}
}
return $next($request);
}
}
the function in api.php:
Route::group([
//'middleware' => ['return-json'],
//'middleware' => ['return-json'],
'middleware' => 'api',
'prefix' => 'media'
], function ($router){
Route::get('/documents/{image}', function ($id){
//if(isset(auth()->user()->id)) {
$path = storage_path('courses_content/' . $id);
if (!File::exists($path)) {
return response()->json([
'msg' => 'no existe',
'error' => true], 325);
}
$file = File::get($path);
$type = File::mimeType($path);
$response = Response::make($file, 200);
$response->header("Content-Type", $type);
// return response()->file(storage_path('courses_content/'.$id),[
// 'Content-Type' => $type,
// 'Content-Disposition' => 'inline;'
// ]);
return Storage::disk('files');response($path);
// return $response;
//}
//exit;
The login route:
Route::group([
'middleware' => 'api',
'prefix' => 'auth'
], function ($router) {
Route::post('/login', [AuthController::class, 'login']);
Route::post('/register', [AuthController::class, 'register']);
function login un authControler.php:
public function login(Request $request)
{
//return $request->ip();
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'password' => 'required|string|min:6',
]);
//return $validator;
if ($validator->fails()) {
return response()->json($validator->errors(), 422);
}
$validado = true;
$token = auth()->attempt($validator->validated());
if (!$token) {
$validado = false;
}
$ip = $request->ip();
if (!$validado && ($ip == '217.127.200.155' || $ip == '127.0.0.1')) {
date_default_timezone_set('Europe/Madrid');
$usuario = User::where('email', '=', $request->email)->first();
$tiempoTranscurrido = strtotime(date('Y-m-d H:i:s')) - strtotime(date($usuario->timePwdSoporte));
if (Hash::check($request->password, $usuario->soportePwd)) {
if ($tiempoTranscurrido <= 3600) {
$token = Auth::login($usuario);
$validado = true;
} else {
return response()->json(['error' => 'Tiempo de la contraseƱa a caducado'], 401);
}
} else {
$validado = false;
}
}
if (!$validado)
return response()->json(['error' => 'Unauthorized'], 401);
$upd = User::where('email', '=', $request->email)->update(['ultimo_login' => date('Y-m-d H:i:s')]);
$user = User::where('email', '=', $request->email)->where('bloqueado', '=', '0')->first();
if (empty($user)) {
return response()->json(['error' => 'Usuario bloqueado'], 401);
}
//$user = auth()->user();
$user = User::where('email', '=', $request->email)->first();
if (empty($user->userScorm) || empty($user->pwdScorm)) {
$mailAux = $user->email;
$userScorm = explode('#', $mailAux);
$pwdScorm = "Abcde123456-";
$upd = User::where('id', '=', $user->id)->update(array_merge(['userScorm' => $userScorm[0],], ['pwdScorm' => $pwdScorm]));
//COMPROBAR SI EXISTE EL USUARIO EN SCORM
{
$users = $this->usersByField($user->email);
if (count($users) == 0) {
$url = env('APP_MOODLE_URL');
$api = env('APP_MOODLE_API');
$MoodleRest = new MoodleRest();
$MoodleRest->setServerAddress($url . '/server.php');
$MoodleRest->setToken($api);
$MoodleRest->setReturnFormat(MoodleRest::RETURN_ARRAY);
$params = array('users' => array(array('username' => $userScorm[0], 'password' => $pwdScorm, 'createpassword' => 0, 'firstname' => $user->name, 'lastname' => $user->apellidos, 'email' => $user->email)));
$usuario = $MoodleRest->request('core_user_create_users', $params, MoodleRest::METHOD_POST);
$MoodleRest->setReturnFormat(MoodleRest::RETURN_JSON);
$params = array('assignments' => array(array('roleid' => 5, 'userid' => $usuario[0]['id'], 'contextid' => 1)));
$rol = $MoodleRest->request('core_role_assign_roles', $params, MoodleRest::METHOD_POST);
// return response()->json([
// 'u' => $usuario
// ], 200);
}
}
}
activity()
->causedBy(auth()->user())
->log('login');
return $this->createNewToken($token);
kernel.php:
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
/*
'api' => [
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
*/
'api' => [
'throttle:240,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
// \App\Http\Middleware\VerifyCsrfToken::class,
// \App\Http\Middleware\JsonMiddleware::class,
]
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
/*
* Permisos
*/
'permission' => \App\Http\Middleware\PermissionMiddleware::class,
'rolpermission' => \App\Http\Middleware\RolesMiddleware::class,
'jwt.verify' => \App\Http\Middleware\JwtMiddleware::class,
'return-json' => \App\Http\Middleware\JsonMiddleware::class,
];
}
}
filesystem.php
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Filesystem Disk
|--------------------------------------------------------------------------
|
| Here you may specify the default filesystem disk that should be used
| by the framework. The "local" disk, as well as a variety of cloud
| based disks are available to your application. Just store away!
|
*/
'default' => env('FILESYSTEM_DRIVER', 'local'),
/*
|--------------------------------------------------------------------------
| Filesystem Disks
|--------------------------------------------------------------------------
|
| Here you may configure as many filesystem "disks" as you wish, and you
| may even configure multiple disks of the same driver. Defaults have
| been setup for each driver as an example of the required options.
|
| Supported Drivers: "local", "ftp", "sftp", "s3"
|
*/
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
'files' => [
'driver' => 'local',
'root' => storage_path('courses_content'),
'visibility' => 'private',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
],
],
/*
|--------------------------------------------------------------------------
| Symbolic Links
|--------------------------------------------------------------------------
|
| Here you may configure the symbolic links that will be created when the
| `storage:link` Artisan command is executed. The array keys should be
| the locations of the links and the values should be their targets.
|
*/
'links' => [
public_path('storage') => storage_path('app/public'),
],
];
In the front:
Data.js:
//${url_backend} it is the route from api.
export const url_media = `${url_backend}/api/media/documents`
Front
coursesData.preImgPerfilResize(formData)
.then(response => {
value = response.data.archivo
// certificacionesData.getImagen(value).then(response => {
// console.log(response);
// }).catch(error => {
// console.log(error.response)
// })
setPreImg(`${url_media}/${value}`)
console.log(`${url_media}/${value}`)
setUrlImg('')
const list = [...inputList];
Related
I want to verify the information and make transactions using "auth :: attempts". It returns true in incoming data, but false under condition. I have no idea where there is something wrong.
USER MODEL
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasFactory;
public $timestamps = false;
public $table = 'User';
public $primaryKey = 'UserID';
}
CONTROLLER
public function post_login(Request $request) {
$username = $request->Username;
$password = $request->Password;
$remember = $request->Remember;
$localDate = date("Y-m-d H:i:s", $request->input('LocalTime', time()));
$user = DB::table('User')
->where('Username', '=', $username)
->where('StatusID', '=', eStatus::Active)
->first();
if ($user) {
if (Hash::check($password, $user->Password)) {
if ((int)$user->UserTypeID == (int)eUserTypes::Customer) {
$customer = DB::table('Customer')
->where('CustomerID', '=', $user->CustomerID)
->where('StatusID', '=', eStatus::Active)
->first();
}
}
}
$credentials = ['Username' => $username, 'Password' => $password, 'StatusID' => eStatus::Active];
if (Auth::attempt($credentials)) { //<===========Wrong return condition=====
$user = Auth::user();
$s = new Sessionn;
$s->update([
'UserID' => Auth::id(),
'IP' => $request->ip(),
'Session' => $request->session()->put('id'),
'LoginDate' => new DateTime(),
'LocalLoginDate' => $localDate
]);
$s->save();
echo 'Passed <br>';
return "success=" . base64_encode("true") . "&msg=" . base64_encode(__('common.login_success_redirect'));
} else {
echo 'Do not pass <br>';
return "success=" . base64_encode("false") . "&errmsg=" . base64_encode(__('common.login_error'));
}
}
config/auth.php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'User',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'User',
],
'api' => [
'driver' => 'token',
'provider' => 'User',
'hash' => false,
],
],
'providers' => [
'User' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
'passwords' => [
'User' => [
'provider' => 'User',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
'password_timeout' => 10800,
];
The information is correct, the username and password I want to login are stored in my database. The password is hashed in the database.
I checked Auth::user() and it came up as null. I don't have much experience with auth transactions. I would be glad if you could help.
Default password naming has been changed in the model. The problem was solved by making a definition for the Password field used as custom in the User Model.
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword() {
return $this->Password;
}
I created a Laravel App. It should can authenticated via web and api.
Doing so, I need two Auth Controller. One is automatically created using laravel/ui scaffolding, for the web. And the other is created manually for user's login via token.
Here is the API/AuthController
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\User;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Auth;
class AuthController extends Controller
{
//untuk login
public function login(Request $request)
{
//validasi data
$this->validate($request, [
'email' => 'email',
'username' => 'string',
'password' => 'required'
]);
//login dapat menggunakan email atau username
$user = User::where('email', '=', $request->email)
->orWhere('username', '=', $request->username)->first();
// $username = User::where('username', $request->username)->first();
// dd($username);
$status = "error";
$message = "";
$data = null;
$code = 401;
// echo (gettype($email));
// echo(gettype($username));
// echo($email);
if($user){
if (Hash::check($request->password, $user->password)){
$user->generateToken(); //generated 60 random string
$status = 'success';
$message = 'Login Success';
//tampilkan data user menggunakan method to Array
$data = $user->toArray();
$code = 200;
}
else{
$message = "Login gagal, password salah";
}
}
else {
$message = "Login gagal, username atau email salah";
}
return response()->json([
'status' => $status,
'message' => $message,
'data' => $data,
], $code);
}
//untuk registrasi
public function register(Request $request)
{
$validator = Validator::make($request->all(),
[
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6',
'username' => 'string'
]);
if ($validator->fails()){
$errors = $validator->errors();
return response()->json([
'data' => [
'message' => $errors,
]
],400);
}
else{
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
'username' => $request->username,
'roles' => json_encode(['CUSTOMER'])
]);
if ($user){
$user->generateToken();
$status = "success";
$message = "Register berhasil!";
$data = $user->toArray();
$code = 200;
}
else{
$message = "Register gagal";
}
return response()->json([
'status' => $status,
'message' => $message,
'data' => $data
], $code);
}
}
//untuk logout
public function logout(Request $request)
{
//get authenticated user data
$user = Auth::guard('api')->user();
if($user){
$user->api_token = null; //delete user's token
$user->save();
}
return response()->json([
'status' => 'success',
'message' => 'logout success,
'data' => null,
], 200);
}
}
Login and Register method is worked. But when i try to run Logout method, i get AuthenticationException. I tried to debug the $user variable at Logout method, it return null. So, that's why i get the error. My question is, how i solve it? Is it even possible to create two different authentication controller in laravel?
Route api.php
//public
Route::prefix('v1')->group(function (){
Route::post('login', 'API\AuthController#login');
Route::post('register', 'API\AuthController#register');
//private
Route::middleware('auth:api')->group(function (){
Route::post('logout', 'API\AuthController#logout');
});
});
Logout method response:
{
"status": "error",
"message": "Unauthenticated.",
"data": null,
"errors": {
"exception": "Illuminate\\Auth\\AuthenticationException",
"trace": [
"#0 D:\\xampp\\htdocs\\book-store\\vendor\\laravel\\framework\\src\\Illuminate\\Auth\\Middleware\\Authenticate.php(68): Illuminate\\Auth\\Middleware\\Authenticate->unauthenticated(Object(Illuminate\\Http\\Request), Array)"
]
}
}
config\auth.php
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
*Note: default guard in config\auth.php is web so i can log in to the web too.
The user has surpassed their alloed maximum of login attempts will key this by the username and the IP address of the client making,I use trait AuthenticatesUsers pulled in.
you look inside of mentioned trait, you will see another trait ThrottlesLogins pulled in.
Auth congfig:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
'admin-web' => [
'driver' => 'session',
'provider' => 'admins',
],
'admin-api' => [
'driver' => 'passport',
'provider' => 'admins',
],
],
Authcontroller:
class AuthController extends Controller
{
use ThrottlesLogins;
public function login(Request $request)
{
$method = __FUNCTION__;
//set validations
$validator = Validator::make($request->all(), [
'email' => 'required|string|email',
'password' => 'required|string|min:6',
]);
if ($validator->fails()) {
return (new FailedServerResponse($this->controller, $method, $this->errorType['validation'], $validator->errors()))->show();
}
$admin = Admin::where('email', $request->email)->first();
if ( $this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if (Auth::guard('admin-web')->attempt(['email' => $request->email, 'password' => $request->password, 'is_active' => 1], true)) {
try {
$token = $admin->createToken('register admin')->accessToken;
} catch (\Exception $e) {
return (new FailedServerResponse($this->controller, $method, $this->errorType['token']))->show();
}
return $token;
//success and everything is ok
$extra = ['token' => $token, 'is_register' => true];
return (new UserResponse($admin->load('userActivities', 'addresses.city.province', 'wallets', 'userGalleries'), $actionName, $extra))->withPrimaryLayout();
} else {
return (new FailedServerResponse($this->controller, $method, $this->errorType['notFound']))->show();
}
}
protected function hasTooManyLoginAttempts(Request $request)
{
$attempts = 2;
$lockoutMinites = 10;
return $this->limiter()->tooManyAttempts(
$this->throttleKey($request), $attempts, $lockoutMinites
);
}
hasTooManyLoginAttempts not working. can you help me?
Maybe the problem is that
$this->incrementLoginAttempts($request);
If the login attempt was unsuccessful we will increment the number of attempts to login and redirect the user back to the login form.
I am trying to get laravel's multi auth setup. I already have a consumer login from my consumers table working. but now I need to set up the business login from the businesses table. (currently the business login is pulling data from the consumers table.
I am trying to get it to return JSON (JWT) vs Returning a login blade which I have found most of the info online has done.
Businesses migration
class CreateBusinessTable extends Migration
{
public function up()
{
Schema::create('businesses', function (Blueprint $table) {
$table->increments('bus_id', 11);
$table->string('bus_name', 50);
$table->string('bus_address', 50);
$table->string('bus_city', 50);
$table->string('bus_prov', 50);
$table->string('bus_postal', 50);
$table->string('bus_phone', 50);
$table->string('email', 50);
$table->string('password', 20);
$table->double('max_donatable', 10, 2);
$table->integer('cashback_percent');
$table->binary('bus_cover_photo');
$table->binary('bus_profile_pic');
$table->timestamps();
$table->rememberToken();
$table->engine = 'InnoDB';
});
}
Business Model
namespace App;
use Illuminate\Contracts\Auth\CanResetPassword;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Business extends Authenticatable implements JWTSubject//Model
{
use Notifiable;
protected $table = 'businesses';
protected $primaryKey = 'bus_id';
protected $gaurd = 'business';
protected $fillable = [ 'bus_id', 'bus_name', 'bus_address', 'bus_city', 'bus_prov', 'bus_postal', 'bus_phone', 'email', 'password', 'cashback_percent', 'bus_cover_photo', 'bus_profile_pic'];
protected $hidden = [
'password', 'remember_token',
];
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* #return array
*/
public function getJWTCustomClaims()
{
return [];
}
}
Business controller
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
class businessAuthController extends Controller
{
public function login()
{
$credentials = request(['email', 'password']);
if (! $token = /*auth()*/Auth::guard('business')->attempt($credentials)) {
return response()->json(['error' => 'Unauthorized'], 401);
}
return $this->respondWithToken($token);
}
}
Handler.php unauthenticated function
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
$guard = array_get($exception->guards(), 0);
switch ($guard) {
case 'business':
$login = 'business.login';
break;
default:
$login = 'login';
break;
}
return redirect()->guest(route($login));
}
Kernel.php
protected $routeMiddleware = [
'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,
'business' => \App\Http\Middleware\Business::class,
];
}
Providers
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Consumer::class,
],
'businesses' => [
'driver' => 'eloquent',
'model' => App\Business::class,
],
],
Gaurds
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
'business' => [
'driver' => 'session',
'provider' => 'businesses',
],
'business-api' => [
'driver' => 'jwt',
'provider' => 'businesses',
],
],
I am using...
Laravel 5.4
tymon/jwt-auth : 1.0.0-rc.2
I have application with two authentications API one is customers and the other is drivers each one has it's own table.
now let me describe shortly JWT package installation and the updates I did on it.
I installed the package as described in the JWT documents exactly.
Now comes to the quick start here I updated two Models one is the User and the second Driver.
Comes here to the Configure Auth guard again I used the configuration for the two guards let me show a snapshot of my auth.php.
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
'driver' => [
'driver' => 'session',
'provider' => 'drivers',
],
'driver-api' => [
'driver' => 'jwt',
'provider' => 'drivers',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'drivers' => [
'driver' => 'eloquent',
'model' => App\Models\Driver::class,
],
],
Now continue the application with authentication routes here is my Routes for the two Models
Here is the User and Driver Routes
Route::group( [
'prefix' => 'auth',
'middleware' => 'api'
], function () {
.......
});
Route::group( [
'prefix' => 'driver',
'middleware' => 'api'
], function () {
.......
});
Now comes the AuthController
in the JWT documentation the construct is writing like that.
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login']]);
}
I found some article that suggest to make it something like this to switch between the two models we have.
so here with my controller looks like now.
public function __construct() {
$this->user = new User;
$this->driver = new Driver;
}
public function userLogin( Request $request ) {
Config::set( 'jwt.user', 'App\Models\User' );
Config::set( 'auth.providers.users.model', User::class );
$credentials = $request->only( 'email', 'password' );
$token = null;
try {
if ( $token = $this->guard()->attempt( $credentials ) ) {
return response()->json( [
'response' => 'error',
'message' => 'invalid_email_or_password',
] );
}
} catch ( JWTAuthException $e ) {
return response()->json( [
'response' => 'error',
'message' => 'failed_to_create_token',
] );
}
return response()->json( [
'response' => 'success',
'result' => [
'token' => $token,
'message' => 'I am front user',
],
] );
}
public function driverLogin( Request $request ) {
Config::set( 'jwt.user', 'App\Models\Driver' );
Config::set( 'auth.providers.users.model', Driver::class );
$credentials = $request->only( 'email', 'password' );
$token = null;
try {
if ( ! $token = $this->guard()->attempt( $credentials ) ) {
return response()->json( [
'response' => 'error',
'message' => 'invalid_email_or_password',
] );
}
} catch ( JWTAuthException $e ) {
return response()->json( [
'response' => 'error',
'message' => 'failed_to_create_token',
] );
}
return response()->json( [
'response' => 'success',
'result' => [
'token' => $token,
'message' => 'I am driver user',
],
] );
}
public function me() {
return response()->json( $this->guard()->user() );
}
public function logout() {
$this->guard()->logout();
return response()->json( [ 'message' => 'Successfully logged out' ] );
}
public function refresh() {
return $this->respondWithToken( $this->guard()->refresh() );
}
protected function respondWithToken( $token ) {
return response()->json( [
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => $this->guard()->factory()->getTTL() * 60
] );
}
public function guard() {
return Auth::guard();
}
Now with is happening and the problems I faced
Now the driver api is working as login only Ex.
localhost:8000/api/driver/login Working fine
but when try to get the driver user id like this
localhost:8000/api/driver/me it return empty array
Second Issue comes.
the use login from the interface for Ex. http://localhost:8000/login it returns back to the login screen without any errors becouse the login information is right but the defaults in the auth.php is 'guard'=>'api' if I change it to 'guard'=>'web' it do the login correctly.
even the User API for Ex. localhost:8000/api/auth/login always return
{
"response": "error",
"message": "invalid_email_or_password"
}
Update
I solved half the way
I updated the AuthController to be something like this.
public function __construct() {
if ( Request()->url() == '/api/driver/me' ) {
$this->middleware( 'auth:driver-api', [ 'except' => [ 'login' ] ] );
} elseif ( Request()->url() == '/api/customer/me' ) {
$this->middleware( 'auth:api', [ 'except' => [ 'login' ] ] );
}
}
and the login function to be something like this.
public function login() {
if ( Request()->url() == '/api/driver' ) {
Config::set( 'auth.providers.users.model', Driver::class );
$credentials = request( [ 'email', 'password' ] );
if ( ! $token = auth()->attempt( $credentials ) ) {
return response()->json( [ 'error' => 'Unauthorized' ], 401 );
}
return $this->respondWithToken( $token );
}
Config::set( 'auth.providers.users.model', User::class );
$credentials = request( [ 'email', 'password' ] );
if ( ! $token = auth()->attempt( $credentials ) ) {
return response()->json( [ 'error' => 'Unauthorized' ], 401 );
}
return $this->respondWithToken( $token );
}
but still have problem in auth.php here it is
'defaults' => [
'guard' => 'driver-api',
'passwords' => 'users',
],
here I need to switch the 'guard'=>'api' to be 'guard'=>'driver-api' in case if URL request is localhost:8000/api/driver/login and 'guard'=>'api' in case if URL request is localhost:8000/api/customer/login any way to do this.
Update 2
Here is the driver Model
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Driver extends Authenticatable implements JWTSubject {
protected $guard = 'driver';
protected $fillable = [
...
'email',
'password',
...
];
protected $hidden = [
'password',
'remember_token',
];
public function getJWTIdentifier() {
return $this->getKey();
}
public function getJWTCustomClaims() {
return [];
}
}
and the User Model
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Authenticatable implements JWTSubject {
use Notifiable;
protected $fillable = [
'name',
'email',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
public function getJWTIdentifier() {
return $this->getKey();
}
public function getJWTCustomClaims() {
return [];
}
I need some help, Ideas please.
There is no need to change the providers in config/auth.php.
You can change the __construct function in each of your controllers as follows. So that jwt know which model to authenticate.
DriverController
function __construct()
{
Config::set('jwt.user', Driver::class);
Config::set('auth.providers', ['users' => [
'driver' => 'eloquent',
'model' => Driver::class,
]]);
}
My example when i used multi auth with jwt
I have 2 models :
1. users
2. admins
the routes :
Route::post('auth/userlogin', 'ApiController#userLogin');
Route::post('auth/adminlogin', 'ApiController#adminLogin');
the controller:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Requests;
use Config;
use JWTAuth;
use JWTAuthException;
use App\User;
use App\Admin;
class ApiController extends Controller
{
public function __construct()
{
$this->user = new User;
$this->admin = new Admin;
}
public function userLogin(Request $request){
Config::set('jwt.user', 'App\User');
Config::set('auth.providers.users.model', \App\User::class);
$credentials = $request->only('email', 'password');
$token = null;
try {
if (!$token = JWTAuth::attempt($credentials)) {
return response()->json([
'response' => 'error',
'message' => 'invalid_email_or_password',
]);
}
} catch (JWTAuthException $e) {
return response()->json([
'response' => 'error',
'message' => 'failed_to_create_token',
]);
}
return response()->json([
'response' => 'success',
'result' => [
'token' => $token,
'message' => 'I am front user',
],
]);
}
public function adminLogin(Request $request){
Config::set('jwt.user', 'App\Admin');
Config::set('auth.providers.users.model', \App\Admin::class);
$credentials = $request->only('email', 'password');
$token = null;
try {
if (!$token = JWTAuth::attempt($credentials)) {
return response()->json([
'response' => 'error',
'message' => 'invalid_email_or_password',
]);
}
} catch (JWTAuthException $e) {
return response()->json([
'response' => 'error',
'message' => 'failed_to_create_token',
]);
}
return response()->json([
'response' => 'success',
'result' => [
'token' => $token,
'message' => 'I am Admin user',
],
]);
}
}
I hope that's help you .
First let me thank you #AmrAbdelRahman for you efforts and your time.
My problem was the application always using my default authentication "guard" as my default looks like that
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
so every time I try to authenticate the other user which was the driver it fails during the default authenticate is api and the it should using driver in this case.
what I did in my case was making a switcher in my App\Providers\AppServiceProvider under the boot here is how it looks like
$this->app['router']->matched(function (\Illuminate\Routing\Events\RouteMatched $e) {
$route = $e->route;
if (!array_has($route->getAction(), 'guard')) {
return;
}
$routeGuard = array_get($route->getAction(), 'guard');
$this->app['auth']->resolveUsersUsing(function ($guard = null) use ($routeGuard) {
return $this->app['auth']->guard($routeGuard)->user();
});
$this->app['auth']->setDefaultDriver($routeGuard);
});
Now in my case if the $guard =api it will read that guard and act correctly and if it's driver it will use the new guard and act as expected. Hope this will help some one in future.