Lumen/Laravel session for specific route - laravel

I am trying to get working Lumen session but only for a specific route, since on other I don't need it.
All I find is to enable middlewhere like
$app->middleware([
'Illuminate\Cookie\Middleware\EncryptCookies',
'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
'Illuminate\Session\Middleware\StartSession',
'Illuminate\View\Middleware\ShareErrorsFromSession',
]);
(source https://stackoverflow.com/a/32635502/1861519)
But this will do a global session setting. But I needed it only as sad on specific route.

All app level middleware goes here
$app->middleware([
\Illuminate\Cookie\Middleware\EncryptCookies,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse ]);
Custom middleware that need session
$app->routeMiddleware([
'session' => \Illuminate\Session\Middleware\StartSession]);
Now add it in route
$app->get('/protected', ['middleware' => 'session', 'uses' => 'ProtectedController#index'])

You can try this when use session on specific routes:
$session = $request->session();
$session->put('foo', 'bar');
echo $session->get('foo');
$session->save();
save() will persist the session file for you.

Related

Laravel socialite dynamic redirectUrl not working in multi-tenant app

i have a multi-tenant app and i am trying to add Facebook linking in it i have tried the process using laravel socialite but i have a problem that when i use dynamic redirect url like so
return Socialite::driver('facebook')
->with([
'redirect_uri' => "https://" . $dynamichost . "/social/facebook/callback",
])
->redirect();
or this way
return Socialite::driver('facebook')->redirectUrl('https://' . $dynamichost .
'/social/facebook/callback')->redirect();
facebook returns error url mismatch. Note i also have set a value for redirect_url in .env
then i have services values like this
'facebook' => [
'client_id' => env('FACEBOOK_APP_ID'),
'client_secret' => env('FACEBOOK_APP_SECRET'),
'redirect' => env('CALLBACK_URL_FACEBOOK'),
'default_graph_ve`enter code here`rsion' => 'v3.3',
],
my guess is socialite somehow set the redirect url equal to the value which is coming from .env and when i change it dynamically it still thinks that url will be like the value of .env and i have tested this scenario the request get success response if keep the redirect url static.
Any suggestions how can i overcome this. thanks.
if you want to use custom redirect-uri dynamic :
use Socialite;
use Laravel\Socialite\Two\FacebookProvider;
$socialite = Socialite::buildProvider(
FacebookProvider::class, [
'client_id' => 'your_id',
'client_secret' => 'your_secret',
'redirect' => 'url',
'default_graph_version' => 'v3.3', //not sure if this needed as far as i know, in socialite the version is defined
]
)->redirect();
well it was dumb mistake i had to match the redirect url in callback handling method. its fixed now thanks.

How to chose guard for session driver

I'm trying to create a login page with laravel web route. When user login, a session record will be saved to database. But in session table, user_id always get null value.
I've found that in Illuminate\Session\DatabaseSessionHandler, function userId() always return null. It's because I set default guard for api. This is my config/auth.php:
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
When I change default guard to web, column user_id in database has value is authorized user id. I don't want to change my default guard to web.
How can I set guard driver for session? Is there something like Auth, we can use Auth::guard('web').
Thanks
Typically, API's are not associated with keeping session state between requests.
You can always add additional groups with seperate guards to the same routes and use them according to your needs. E.g.
Route::group(['middleware' => 'auth:api'], function () {
Route::post('/user', 'UserController#apiUser');
}
Route::group(['middleware' => 'auth'], function () {
Route::post('/user', 'UserController#index');
}
and then seperately reference
$user = auth('web')->user();
or
$user = auth('api')->user();
Read here for a Laravel API implementation using Passport. You may also want to consider Laravel Sanctum which offers support for API token generation for your users.

Laravel 5.4 route simplification

I've been trying to find some documentation on how to accomplish the following, but it seems like maybe I'm not using the correct search terms.
I would like to implement some simplified routes in Laravel 5.4 by omitting the route name from the path – for example:
/{page} instead of /pages/{page}
/profile instead of /users/{user}/edit
/{exam}/{question} (or even /exams/{exam}/{question}) instead of /exams/{exam}/questions/{question}
Example of current routes
Route::resource('exams.questions', 'ExamQuestionController', ['only' => ['show']]);
// exams/{exam}/question/{question}
I know how to do this with route closures and one-off routes (e.g.: Route::get...) but is there a way to do this using Route::resource?
In rails the above could be accomplished with:
resources :exams, path: '', only: [:index, :show] do
resources :question, path: '', only: [:show]
end
// /:exam_id/:id
While I haven't yet found a way to accomplish my test cases using strictly Route::resource, here is what I implemented to accomplish what I was trying to do:
// For: `/{exam}/{question}`
Route::group(['as' => 'exams.', 'prefix' => '{exam}'], function() {
Route::get('{question}', [
'as' => 'question.show',
'uses' => 'QuestionController#show'
]);
});
// For: `/exams/{exam}/{question}`
Route::group(['as' => 'exams.', 'prefix' => 'exams/{exam}'], function() {
Route::get('{question}', [
'as' => 'question.show',
'uses' => 'QuestionController#show'
]);
});
// For: `/profile`
Route::get('profile', function() {
$controller = resolve('App\Http\Controllers\UserController');
return $controller->callAction('edit', $user = [ Auth::user() ]);
})->middleware('auth')->name('users.edit');
// For: `/{page}`
// --------------
// Note that the above `/profile` route must come before
// this route if using both methods as this route
// will capture `/profile` as a `{page}` otherwise
Route::get('{page}', [
'as' => 'page.show',
'uses' => 'PageController#show'
]);
No, you cannot and should not be trying to do this with Route::resource.
The whole purpose of Route::resource is that it creates the routes in a specific way that matches the common "RESTful Routing" pattern.
There is nothing wrong with wanting simpler routes (no one is forcing you to use RESTful routing), but you will need to make them yourself with Route::get, etc. as you already know.
From the documentation (not exactly your case, but related to it - showing that Route::resource is not meant to be super-configurable):
Supplementing Resource Controllers
If you need to add additional routes to a resource controller beyond the default set of resource routes, you should define those routes before your call to Route::resource; otherwise, the routes defined by the resource method may unintentionally take precedence over your supplemental routes:
Route::get('photos/popular', 'PhotoController#method');
Route::resource('photos', 'PhotoController');

Laravel 5.2 Auth::login($user) not working

I am writing a Laravel 5.2 application. I need to manually login the user for which I am using \Auth::login($user). I am doing it in following way.
if ($user = User::where('phone',session('phone'))->first())
{
\Auth::login($user);
// \Auth::loginUsingId($user->id);
// Auth::attempt(['email' => $user->email, 'password' => 'password']);
$data = \Auth::user(); //returning correct results
}
I have tried all the options namely Auth::login($user), Authh:loginUsingId($user->id) and attempt method. These methods are working fine as the $data variable is storing the object of correct user. But the problem is when I move to other route say '/home' the user remain no more authenticated.
What might be the wrong here? How could I do it correctly?
Since Laravel 5.2, you have to attach all your routes that need session with the 'web' middleware. See your app/Http/Kernel.php, the 'web' middleware contains the \Illuminate\Session\Middleware\StartSession.
In routes you have to use web in laravel 5.2
Route::group(['middleware' => ['web', 'auth']], function () {
Route::get('/', 'HomeController#index');
Route::get('/profile', 'HomeController#profile');
});

Laravel middleware detected but not executed

I have a middleware which works fine when defined as a global middleware in Kernel.php. However, I want it to be applied only to specific routes, so I do this:
Route::group(['prefix' => 'myapi/', 'middleware' => 'api'], function(){
});
Calling php artisan route:list shows that the middleware is detected correctly. However, it does not get executed (I know this because even purposely placing an error in the file does not do anything).
...
protected $middlewareGroups = [
...
'api' => [
'throttle:60,1',
\App\Http\Middleware\CORSMiddleware::class,
],
];
When the middleware is set as global, it does not get listed by route:list. Also, purposely specifying a wrong middleware name in routes.php does not throw any error.
EDIT:
Logging shows that the middleware is executed for all GET ressource routes, but not for POST/PUT/DELETE.
I believe middleware has to be placed inside an array when adding it to a group - that will cause it to trigger and give you the expected result:
Route::group(['prefix' => 'myapi/', 'middleware' => ['api']], function(){
});

Resources