Laravel Localization Routes in Jetstream & Fortify - laravel

I am using Laravel 8 with the Jetstream and Fortify authentication module. All the auth module works, on the other hand I was in the process of making the site in multi-languages, and I found myself with errors in authentication.
My problem today is the following, when the user finishes registering, he must check his email, or Laravel tells me the following error :
> Illuminate\Routing\Exceptions\UrlGenerationException
Missing required parameter for [Route: verification.verify] [URI: {locale}/email/verify/{id}/{hash}] [Missing parameter: locale].
But, for the others routes like /en/login, /en/register, /en/user/profile ..., they work fine ! The error is just for the email validation, please help, thanks. To have control over my authentication routes, I ignored the default JetStream & Fortify routes in the app/providers
routes/web.php
<?php
use Illuminate\Support\Facades\Route;
Route::get('/', function(){
return redirect()->route('home-locale', app()->getLocale());
})->name('home');
Route::group([
'prefix' => '{locale}',
'where' => ['locale' => '[a-zA-Z]{2}']], function(){
Route::get('/', 'HomeController#index')->name('home-locale');
Auth::routes();
});
Route::get('/index', 'HomeController#index');
Route::post('/map-agents','MapController#ajaxRequestMap')->name('*','map.agents');
Route::post('/map-agents/agents','MapController#ajaxRequestAgent');
Route::group([
'middleware' => ['auth:sanctum', 'verified'],
'prefix' => '{locale}',
'where' => ['locale' => '[a-zA-Z]{2}']],
function (){
Route::get('/dashboard', 'DashboardController#index')->name('dashboard');
});
Route::group([
'middleware' => ['auth'],
'prefix' => '{locale}',
'where' => ['locale' => '[a-zA-Z]{2}']],
function (){
Route::resource('agents', AgentsController::class);
});
routes/fortify.php
<?php
use Illuminate\Support\Facades\Route;
use Laravel\Fortify\Features;
use Laravel\Fortify\Http\Controllers\AuthenticatedSessionController;
use Laravel\Fortify\Http\Controllers\ConfirmablePasswordController;
use Laravel\Fortify\Http\Controllers\ConfirmedPasswordStatusController;
use Laravel\Fortify\Http\Controllers\EmailVerificationNotificationController;
use Laravel\Fortify\Http\Controllers\EmailVerificationPromptController;
use Laravel\Fortify\Http\Controllers\NewPasswordController;
use Laravel\Fortify\Http\Controllers\PasswordController;
use Laravel\Fortify\Http\Controllers\PasswordResetLinkController;
use Laravel\Fortify\Http\Controllers\ProfileInformationController;
use Laravel\Fortify\Http\Controllers\RecoveryCodeController;
use Laravel\Fortify\Http\Controllers\RegisteredUserController;
use Laravel\Fortify\Http\Controllers\TwoFactorAuthenticatedSessionController;
use Laravel\Fortify\Http\Controllers\TwoFactorAuthenticationController;
use Laravel\Fortify\Http\Controllers\TwoFactorQrCodeController;
use Laravel\Fortify\Http\Controllers\VerifyEmailController;
Route::group([
'middleware' => config('fortify.middleware', ['web']),
'prefix' => '{locale}',
'where' => ['locale' => '[a-zA-Z]{2}']],
function () {
$enableViews = config('fortify.views', true);
// Authentication...
if ($enableViews) {
Route::get('/login', [AuthenticatedSessionController::class, 'create'])
->middleware(['guest'])
->name('login');
}
$limiter = config('fortify.limiters.login');
$twoFactorLimiter = config('fortify.limiters.two-factor');
Route::post('/login', [AuthenticatedSessionController::class, 'store'])
->middleware(array_filter([
'guest',
$limiter ? 'throttle:'.$limiter : null,
]));
Route::post('/logout', [AuthenticatedSessionController::class, 'destroy'])
->name('logout');
// Password Reset...
if (Features::enabled(Features::resetPasswords())) {
if ($enableViews) {
Route::get('/forgot-password', [PasswordResetLinkController::class, 'create'])
->middleware(['guest'])
->name('password.request');
Route::get('/reset-password/{token}', [NewPasswordController::class, 'create'])
->middleware(['guest'])
->name('password.reset');
}
Route::post('/forgot-password', [PasswordResetLinkController::class, 'store'])
->middleware(['guest'])
->name('password.email');
Route::post('/reset-password', [NewPasswordController::class, 'store'])
->middleware(['guest'])
->name('password.update');
}
// Registration...
if (Features::enabled(Features::registration())) {
if ($enableViews) {
Route::get('/register', [RegisteredUserController::class, 'create'])
->middleware(['guest'])
->name('register');
}
Route::post('/register', [RegisteredUserController::class, 'store'])
->middleware(['guest']);
}
// Email Verification...
if (Features::enabled(Features::emailVerification())) {
if ($enableViews) {
Route::get('/email/verify', [EmailVerificationPromptController::class, '__invoke'])
->middleware(['auth'])
->name('verification.notice');
}
Route::get('/email/verify/{id}/{hash}', [VerifyEmailController::class, '__invoke'])
->middleware(['auth', 'signed', 'throttle:6,1'])
->name('verification.verify');
Route::post('/email/verification-notification', [EmailVerificationNotificationController::class, 'store'])
->middleware(['auth', 'throttle:6,1'])
->name('verification.send');
}
// Profile Information...
if (Features::enabled(Features::updateProfileInformation())) {
Route::put('/user/profile-information', [ProfileInformationController::class, 'update'])
->middleware(['auth'])
->name('user-profile-information.update');
}
// Passwords...
if (Features::enabled(Features::updatePasswords())) {
Route::put('/user/password', [PasswordController::class, 'update'])
->middleware(['auth'])
->name('user-password.update');
}
// Password Confirmation...
if ($enableViews) {
Route::get('/user/confirm-password', [ConfirmablePasswordController::class, 'show'])
->middleware(['auth'])
->name('password.confirm');
Route::get('/user/confirmed-password-status', [ConfirmedPasswordStatusController::class, 'show'])
->middleware(['auth'])
->name('password.confirmation');
}
Route::post('/user/confirm-password', [ConfirmablePasswordController::class, 'store'])
->middleware(['auth']);
// Two Factor Authentication...
if (Features::enabled(Features::twoFactorAuthentication())) {
if ($enableViews) {
Route::get('/two-factor-challenge', [TwoFactorAuthenticatedSessionController::class, 'create'])
->middleware(['guest'])
->name('two-factor.login');
}
Route::post('/two-factor-challenge', [TwoFactorAuthenticatedSessionController::class, 'store'])
->middleware(array_filter([
'guest',
$twoFactorLimiter ? 'throttle:'.$twoFactorLimiter : null,
]));
$twoFactorMiddleware = Features::optionEnabled(Features::twoFactorAuthentication(), 'confirmPassword')
? ['auth', 'password.confirm']
: ['auth'];
Route::post('/user/two-factor-authentication', [TwoFactorAuthenticationController::class, 'store'])
->middleware($twoFactorMiddleware);
Route::delete('/user/two-factor-authentication', [TwoFactorAuthenticationController::class, 'destroy'])
->middleware($twoFactorMiddleware);
Route::get('/user/two-factor-qr-code', [TwoFactorQrCodeController::class, 'show'])
->middleware($twoFactorMiddleware);
Route::get('/user/two-factor-recovery-codes', [RecoveryCodeController::class, 'index'])
->middleware($twoFactorMiddleware);
Route::post('/user/two-factor-recovery-codes', [RecoveryCodeController::class, 'store'])
->middleware($twoFactorMiddleware);
}
});
routes/jetstream.php
<?php
use Illuminate\Support\Facades\Route;
use Laravel\Jetstream\Http\Controllers\CurrentTeamController;
use Laravel\Jetstream\Http\Controllers\Livewire\ApiTokenController;
use Laravel\Jetstream\Http\Controllers\Livewire\PrivacyPolicyController;
use Laravel\Jetstream\Http\Controllers\Livewire\TeamController;
use Laravel\Jetstream\Http\Controllers\Livewire\TermsOfServiceController;
use Laravel\Jetstream\Http\Controllers\Livewire\UserProfileController;
use Laravel\Jetstream\Http\Controllers\TeamInvitationController;
use Laravel\Jetstream\Jetstream;
Route::group(
[
'middleware' => config('jetstream.middleware', ['web']),
'prefix' => '{locale}',
'where' => ['locale' => '[a-zA-Z]{2}']],
function () {
if (Jetstream::hasTermsAndPrivacyPolicyFeature()) {
Route::get('/terms-of-service', [TermsOfServiceController::class, 'show'])->name('terms.show');
Route::get('/privacy-policy', [PrivacyPolicyController::class, 'show'])->name('policy.show');
}
Route::group(['middleware' => ['auth', 'verified']], function () {
// User & Profile...
Route::get('/user/profile', [UserProfileController::class, 'show'])
->name('profile.show');
// API...
if (Jetstream::hasApiFeatures()) {
Route::get('/user/api-tokens', [ApiTokenController::class, 'index'])->name('api-tokens.index');
}
// Teams...
if (Jetstream::hasTeamFeatures()) {
Route::get('/teams/create', [TeamController::class, 'create'])->name('teams.create');
Route::get('/teams/{team}', [TeamController::class, 'show'])->name('teams.show');
Route::put('/current-team', [CurrentTeamController::class, 'update'])->name('current-team.update');
Route::get('/team-invitations/{invitation}', [TeamInvitationController::class, 'accept'])
->middleware(['signed'])
->name('team-invitations.accept');
}
});
});
app/Http/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,
\Laravel\Jetstream\Http\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\SetLocale::class,
],
'api' => [
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::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,
];
}
app/Http/Middleware/setLocale.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class SetLocale
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
$languages = array_keys(config('app.languages'));
$route = $request->route();
if (request('change_language')) {
session()->put('language', request('change_language'));
$language = request('change_language');
if (array_key_exists('locale', $route->parameters) && $route->parameters['locale'] != $language)
{
$route->parameters['locale'] = $language;
if (in_array($language, $languages)) {
app()->setLocale($language);
}
return redirect(route($route->getName(), $route->parameters));
}
} elseif (session('language')) {
$language = session('language');
if (array_key_exists('locale', $route->parameters) && $route->parameters['locale'] != $language && in_array($route->parameters['locale'], $languages))
{
$language = $route->parameters['locale'];
session()->put('language', $language);
}
} elseif (config('app.locale')) {
$language = config('app.locale');
}
if (isset($language) && in_array($language, $languages)) {
app()->setLocale($language);
}
return $next($request);
}
}

Related

Laravel 9 - ERROR: Auth guard [ admin] is not defined

I'm trying to create an Admin Login in Laravel Jetstream. I've created a separate admins table to store the login data. However, I get an error saying Auth guard [ admin] is not defined when I try to access the admin login page through http://localhost:8000/admin/login.
I tried php artisan config:clear and php artisan config:cache commands, but they didn't solve the issue.
auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
'admins' => [
'provider' => 'admins',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
web.php
Route::get('/', function () {
return view('welcome');
});
Route::group(['prefix' => 'admin', 'middleware' => ['admin:admin']], function () {
Route::get('/login', [AdminController::class, 'loginForm']);
Route::post('/login', [AdminController::class, 'store'])->name('admin.login');
});
Route::middleware(['auth:sanctum, admin', config('jetstream.auth_session'), 'verified'])->group(function () {
Route::get('/admin/dashboard', function () {
return view('dashboard');
})->name('dashboard');
});
Route::middleware(['auth:sanctum, web', config('jetstream.auth_session'), 'verified'])->group(function () {
Route::get('/dashboard', function () {
return view('dashboard');
})->name('dashboard');
});
AdminController
public function loginForm()
{
return view('auth.login', ['guard' => 'admin']);
}
AdminRidirectIfAuthenticated.php
public function handle(Request $request, Closure $next, ...$guards)
{
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
return redirect($guard . '/dashboard');
}
}
return $next($request);
}
LoginResponse.php
public function toResponse($request)
{
return $request->wantsJson()
? response()->json(['two_factor' => false])
: redirect()->intended('admin/dashboard');
}
Kernel.php
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'admin' => \App\Http\Middleware\AdminRedirectIfAuthenticated::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,
];
FortifyServiceProvider.php
use App\Http\Controllers\AdminController;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Support\Facades\Auth;
use App\Actions\Fortify\AttemptToAuthenticate;
use App\Actions\Fortify\RedirectIfTwoFactorAuthenticatable;
public function register()
{
$this->app->when([AdminController::class, AttemptToAuthenticate::class, RedirectIfTwoFactorAuthenticatable::class])
->needs(StatefulGuard::class)
->give(function () {
return Auth::guard('admin');
});
}
login.blade.php
<form method="POST" action="{{ isset($guard) ? url($guard.'/login') : route('login') }}">
#csrf
..............
</form>
AdminStatefulGuard.php
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Guard;
interface AdminStatefulGuard extends Guard
{
/**
* Attempt to authenticate a user using the given credentials.
*
* #param array $credentials
* #param bool $remember
* #return bool
*/
public function attempt(array $credentials = [], $remember = false);
/**
* Log a user into the application without sessions or cookies.
*
* #param array $credentials
* #return bool
*/
public function once(array $credentials = []);
/**
* Log a user into the application.
*
* #param \Illuminate\Contracts\Auth\Authenticatable $user
* #param bool $remember
* #return void
*/
public function login(Authenticatable $user, $remember = false);
/**
* Log the given user ID into the application.
*
* #param mixed $id
* #param bool $remember
* #return \Illuminate\Contracts\Auth\Authenticatable|bool
*/
public function loginUsingId($id, $remember = false);
/**
* Log the given user ID into the application without sessions or cookies.
*
* #param mixed $id
* #return \Illuminate\Contracts\Auth\Authenticatable|bool
*/
public function onceUsingId($id);
/**
* Determine if the user was authenticated via "remember me" cookie.
*
* #return bool
*/
public function viaRemember();
/**
* Log the user out of the application.
*
* #return void
*/
public function logout();
}
Remove space before middleware parameter at web.php
Remove space before admin at 'auth:sanctum, admin'

use laravel jwt authentication only for api without affecting web

I have an issue with authentication in laravel web, I only what to use the JWT authentication for the api only, I notice whenever I change guard in defaults to web 'guard' => 'web' and I try to login with postman using my api it will not work and this error show("message": "Method Illuminate\Auth\SessionGuard::factory does not exist.") but the web will work, if I change it to 'guard' => 'api' I will not be able to login in the web but the api postman login will work.
Only web will work
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
Only api will work
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
Route
Route::group([
'prefix' => 'auth'
], function () {
Route::post('login', [AuthController::class, 'login']);
Route::post('logout', [AuthController::class, 'logout']);
Route::post('refresh', [AuthController::class, 'refresh']);
Route::post('me', [AuthController::class, 'me']);
});
Controller
class AuthController extends Controller
{
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login']]);
}
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if ($token = $this->guard()->attempt($credentials)) {
return $this->respondWithToken($token);
}
return response()->json(['error' => 'Unauthorized'], 401);
}
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();
}
}
I just want to use JWT authentication for only the api without affecting the web, Thanks
What defaults.guard config does is setting the default guard to be used if none specified.
If you want 2 different authentication methods and guards you should specify each by name in your middlewares.
So instead of Route::middleware('auth')->get(...);
you should write Route::middleware('auth:api')->get(...);
If you want to protect all routes in a group you can do it in app/Http/Kernel.php by adding this lines:
protected $middlewareGroups = [
'web' => [
...
'auth:web'
],
'api' => [
...
'auth:api'
],
];
you can use this
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
and in controller where you need api guard use this
auth('api')
for example in login controller
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('api')->attempt($validator->validated())) {
return response()->json(['error' => 'Unauthorized'], 401);
}
$token = auth('api')->claims(['user' => auth('api')->user()])->attempt($validator->validated());
return $this->createNewToken($token);
}
i use this controller and works for me
class UserController extends Controller
{
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login', 'register']]);
}
/**
* Get a JWT via given credentials.
*
* #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('api')->attempt($validator->validated())) {
return response()->json(['error' => 'Unauthorized'], 401);
}
$token = auth('api')->claims(['user' => auth('api')->user()])->attempt($validator->validated());
return $this->createNewToken($token);
// return response()->json([
// 'token' => $this->createNewToken($token),
// ]);
}
/**
* Register a User.
*
* #return \Illuminate\Http\JsonResponse
*/
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required|string|between:2,100',
'email' => 'required|string|email|max:100|unique:users',
'password' => 'required|string|confirmed|min:6',
]);
if ($validator->fails()) {
return response()->json($validator->errors()->toJson(), 400);
}
$user = User::create(array_merge(
$validator->validated(),
['password' => bcrypt($request->password)]
));
return response()->json([
'message' => 'User successfully registered',
'user' => $user,
], 201);
}
/**
* Log the user out (Invalidate the token).
*
* #return \Illuminate\Http\JsonResponse
*/
public function logout()
{
Auth::logout();
return response()->json(['message' => 'User successfully signed out']);
}
/**
* Refresh a token.
*
* #return \Illuminate\Http\JsonResponse
*/
public function refresh()
{
return $this->createNewToken(auth::refresh());
}
/**
* Get the authenticated User.
*
* #return \Illuminate\Http\JsonResponse
*/
public function userProfile()
{
return response()->json(auth::user());
}
/**
* Get the token array structure.
*
* #param string $token
*
* #return \Illuminate\Http\JsonResponse
*/
protected function createNewToken($token)
{
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth('api')->factory()->getTTL() * 60,
'user' => auth('api')->user(),
]);
}
}
and routes
Route::prefix('user')->middleware('api')->group(function () {
Route::post('/login', [UserController::class, 'login']);
Route::post('/logout', [UserController::class, 'logout']);
Route::post('/refresh', [UserController::class, 'refresh']);
Route::get('/user-profile', [UserController::class, 'userProfile']);
Route::post('/register', [UserController::class, 'register']);
});

Why CORS Error Access-Control-Allow-Credentials' header in the response is ''?

I make #vue/cli 4.5.9 / axios app with data reading from Laravel 7
Backend REST(with "tymon/jwt-auth": "^1.0", "barryvdh/laravel-cors": "^1.0.5") API using axios
and I got error :
has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'.
But here I check that all Credentials are filled : https://prnt.sc/vsngs5
I have on client side:
console.log('+login settingCredentialsConfig::')
console.log(settingCredentialsConfig)
axios.post(apiUrl + '/login', userCredentials, settingCredentialsConfig)
.then((response) => {
if (typeof response.data.access_token === 'undefined' || typeof response.data.user === 'undefined') {
commit('auth_error') // call auth_error mutation to make changes to vuex store
bus.$emit('authLoggedError')
return
}
I import settingCredentialsConfig from setings file defined as :
export const settingCredentialsConfig = {
withCredentials:true,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials':true
}
}
and in src/main.js axios defined :
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import axios from 'axios'
export const bus = new Vue()
axios.defaults.crossDomain = true
let apiUrl = process.env.VUE_APP_API_URL
Vue.config.productionTip = false
Vue.prototype.$http = axios
Vue.config.productionTip = false
import Vue2Filters from 'vue2-filters'
Vue.use(Vue2Filters)
new Vue({
router,
store,
bus,
render: h => h(App)
}).$mount('#app')
Vue.use({
install (Vue) {
Vue.prototype.$api = axios.create({
baseURL: apiUrl
})
}
})
In other vue page I have request to backend using the same settingCredentialsConfig var and
it works ok. But it does not refere auth of backend User model.
On backenbd part I have app/User.php :
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject; // JWT SUPPORT
class User extends Authenticatable implements JWTSubject // JWT SUPPORT
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function getJWTIdentifier() // JWT SUPPORT
{
return $this->getKey();
}
public function getJWTCustomClaims() // JWT SUPPORT
{
return [];
}
}
In app/Http/Controllers/API/AuthController.php :
<?php
namespace App\Http\Controllers\API;
use Auth;
use Config;
use DB;
use Validator;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\User;
//use Illuminate\Support\Str;
class AuthController extends Controller
{
protected $maxAttempts = 1; // Default is 5
protected $decayMinutes = 1; // Default is 1
/**
* Create a new AuthController instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('jwt.auth', ['except' => ['login', 'register', 'activate']]);
}
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
\Log::info('LOGIN +1 $credentials ::');
if ($token = $this->guard('api')->attempt($credentials /*,['exp' => \Carbon\Carbon::now()->addHours(4)->timestamp]*/)) {
$loggedUser = $this->guard('api')->user();
\Log::info('LOGIN +2 $loggedUser ::');
return $this->respondWithToken($token);
}
\Log::info('LOGIN -3 ::');
return response()->json(['error' => 'Unauthorized'], 401);
}
public function getAuthenticatedUser()
{
try {
\Log::info('-1 getAuthenticatedUser ::');
if ( ! $user = JWTAuth::parseToken()->authenticate()) {
return response()->json(['user_not_found'], 404);
}
} catch (Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
\Log::info('-2 getAuthenticatedUser ::');
return response()->json(['token_expired'], $e->getStatusCode());
} catch (Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {
\Log::info('-3 getAuthenticatedUser ::');
return response()->json(['token_invalid'], $e->getStatusCode());
} catch (Tymon\JWTAuth\Exceptions\JWTException $e) {
\Log::info('-4 getAuthenticatedUser ::');
return response()->json(['token_absent'], $e->getStatusCode());
}
// the token is valid and we have found the user via the sub claim
return response()->json(compact('user'));
}
public function me()
{
return response()->json($this->guard('api')->user());
}
public function logout()
{
\Log::info('-1 logout ::' . print_r(-1, true));
$this->guard('api')->logout();
return response()->json(['message' => 'Successfully logged out']);
}
public function refresh()
{
return $this->respondWithToken($this->guard()->refresh());
}
protected function respondWithToken($token)
{
$loggedUser = $this->guard()->user();
return response()->json([
'access_token' => $token,
'user' => $loggedUser,
'token_type' => 'bearer',
'expires_in' => $this->guard('api')->factory()->getTTL() * 999360 // TOFIX
]);
}
public function guard()
{
return \Auth::Guard('api');
}
}
and in config/cors.php :
<?php
return [
'paths' => ['api/*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];
I generated file config/jwt.php with command :
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
and left it unchanged .
In file app/Http/Kernel.php :
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::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,
'jwt.auth' => 'Tymon\JWTAuth\Middleware\GetUserFromToken',
'jwt.refresh' => 'Tymon\JWTAuth\Middleware\RefreshToken',
...
What did I miss ?
Thanks!
Change the supports_credentials value in your config/cors.php file to true.

Laravel middleware Auth work in controller but not in my middleware

i'm in trouble for 2 days with the laravel auth middlewares.
I have understand how the Auth system work with JWTtoken. In my controller all work fine i got my user login and i can access with Auth::guard->user().
But i have one problem in my middleware Authenticate.php :
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
use Illuminate\Support\Facades\Auth;
use Closure;
class Authenticate extends Middleware
{
protected function redirectTo($request)
{ dd(
$request->user(),
auth()->id() ?? '?',
Auth::id() ?? '?',
$request->user()->id ?? '?',
auth()->check(),
get_class(auth()->guard())
);
}
}
I try everything i found in multiple post or tutorial, but the result is the same (same time in controller all work user is login) :
null
"?"
"?"
"?"
false
"Tymon\JWTAuth\JWTGuard"
AuthController.php
public function __construct()
{
$this->middleware('auth', ['except' => ['login', 'register']]);
}
public function login(Request $request){
$credentials = $request->only('email', 'password');
if(!$token = $this->guard()->attempt($credentials)){
return response()->json(['error' => "L'email ou le mot de passe ne correspondent pas."]);
}else {
return response()->json([
'token' => $token,
]);
}
}
public function guard()
{
return Auth::guard();
}
And Multiple function me,logout...
Kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
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:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::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,
];
}
I have try to take rules in $middlewareGroups web and past in $middleware, and if i do that is say :
"Call to a member function parameters() on null".
So nothing change my Auth is null.
Thanks a lot if someone can explain me the problem and what i do wrong !
EDIT :
api.php
Route::group(['prefix' => 'auth', 'namespace' => 'Auth'], function ($router) {
Route::post('/inscription', 'AuthController#register');
Route::post('/connexion', 'AuthController#login');
Route::get('/logout', 'AuthController#logout');
Route::get('/me', 'AuthController#me');
Route::get('/isAdmin', 'AuthController#isAdmin');
});
Solution not found :(
Authenticate.php
public function handle($request, Closure $next, ...$guards)
{
$this->authenticate($request, $guards);
$user = $this->auth->user();
...do your thing....
Kernel.php
protected $middlewareGroups = [
'api' => [
\Illuminate\Session\Middleware\StartSession::class,
\AEPlanning\Http\Middleware\VerifyCsrfToken::class,
You will get user only after successful login

session not persisting in laravel

I use Session in laravel, but when I get session in controller, it's not work.
web.php
Route::get('locale/{locale}',function ($locale){
//Session::put('locale',$locale);
session(['locale' => $locale]);
Session::save();
return redirect()->back();
});
Localization.php
public function handle($request, Closure $next)
{
if(\Session::has('locale')){
\App::setLocale(\Session::get('locale'));
session(['locale' => \Session::get('locale')]);
\Session::save();
}
return $next($request);
}
Kernel.php
protected $middleware = [
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::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\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\Localization::class,
],
'api' => [
\App\Http\Middleware\EventLogMiddle::class,
'throttle:600,1',
'bindings',
],
];
MachCtrl.php (extends Controller)
public function index()
{
$lang = session('locale');
$config = json_encode([
"table" => "Machine_list",
"title" => "machine list",
"rows" => 20,
"column" => [
"Machine_id", "VM_name", "Machine_location","IP_address",
"Network_status", "Current_status"
],
"CUDP" => "0111",
"CreateRoute" => route('machine.create'),
"DeleteRoute" => route('machine.destroy'),
"UpdateRoute" => route('machine.editInfo'),
"locale" => $lang,
]);
return view('table.show')->with(['config' => $config, 'lang' =>
$lang]);
}
I save Session in router and middlemare, it's not work.
But when I put Session in Controller, it's work. As following code:
public function index()
{
session(['locale' => 'en']);
$lang = session('locale');
$config = json_encode([
"table" => "Machine_list",
"title" => "machine list",
"rows" => 20,
"column" => [
"Machine_id", "VM_name", "Machine_location","IP_address",
"Network_status", "Current_status"
],
"CUDP" => "0111",
"CreateRoute" => route('machine.create'),
"DeleteRoute" => route('machine.destroy'),
"UpdateRoute" => route('machine.editInfo'),
"locale" => $lang,
]);
return view('table.show')->with(['config' => $config, 'lang' =>
$lang]);
}
I really want to know what happen in my project.
Thanks.
Edit:
I use dd(session()) in my code:
-web.php
Route::get('locale/{locale}',function ($locale){
Session::put('locale',$locale);
Session::save();
dd(session());
return redirect()->back();
});
Result:
-Localization.php
public function handle($request, Closure $next)
{
if(\Session::has('locale')){
\App::setLocale(\Session::get('locale'));
session(['locale' => \Session::get('locale')]);
//dd(session());
\Session::save();
}
return $next($request);
}
Result:
-MachCtrl.php
public function index()
{
dd(session());
$lang = session('locale');
$config = json_encode([
"table" => "Machine_list",
"title" => "machine list",
"rows" => 20,
"column" => [
"Machine_id", "VM_name", "Machine_location","IP_address",
"Network_status", "Current_status"
],
"CUDP" => "0111",
"CreateRoute" => route('machine.create'),
"DeleteRoute" => route('machine.destroy'),
"UpdateRoute" => route('machine.editInfo'),
"locale" => $lang,
]);
return view('table.show')->with(['config' => $config, 'lang' =>
$lang]);
}
Result:
Try using a different session driver to round down your issue a little bit.
EDIT: Sorry I can't comment yet, <50rep :(
I checked my working code. I set the whole cycle as:
Language middleware:
class Language
{
protected $app;
public function __construct(Application $app, Request $request) {
$this->app = $app;
}
public function handle($request, Closure $next)
{
$this->app->setLocale(session('user_locale', config('app.locale')));
return $next($request);
}
}
In my middleware Kernel.php:
protected $middlewareGroups = [
'web' => [
\Illuminate\Session\Middleware\StartSession::class,
//...
\App\Http\Middleware\Language::class,
]
];
And in route:
Route::get('locale/{locale}',function ($locale){
session(['user_locale' => $locale]);
});

Resources