Laravel Except Token Mismatch Error - laravel

My URL
http://laravel/tr/order/fp1/success
VerifyCsrfToken Except .
protected $except = [
'order/*'
];
But i have Token Mismatch Error.
Update:
I'm posting data to external webpage (Bank Server) And They are posting to my site.

As per the Op's comment it seems that the request is coming from external site where we can't generate csrf tokens from our application.
So, there is two possible solutions
Method 1 :
The request should get the csrf token from the application in prior request and then send the request with token
Method 2 :
You should attach a parameter with incoming request and have this inside the app\Http\Middleware\VerifyCsrfToken.php
$paramExist= $request->yourSecretParam;
#return parent::handle($request, $next);
if(isset($paramExist))
{
$yourSpecialkey ='a2$%$'; #This to check whether the param has the value that you set
if($paramExist==$yourSpecialKey)
{
return $next($request);
}
else
{
return parent::handle($request, $next);
}
}
else
{
return parent::handle($request, $next);
}
By having this you can check whether the request matches not with the parameter value that the external application has.
Hope, this helps you

I solve the problem.
In Except Property we have to write URI. But i didn't write language path.
protected $except = [
'tr/order/*'
];
If i write language path. It is working. But hardcoding language path is not logical.
And i override shouldPassThrough of BaseVerifier in Laravel.
protected $except = [
'order/*',
];
protected function shouldPassThrough($request)
{
foreach ($this->except as $except) {
if ($request->is(trim(Lang::locale().'/'.$except, '/'))) {
return true;
}
}
return false;
}
We add Lang::locale().'/'
Now we can use except property without writing language path.

Related

Laravel Fortify modify RegisterViewResponse

I am trying to modify the behavior of Fortify Register route.
I am sending out custom register urls, if this url doesn't match my logic I need to redirect to a custom page, so you can not even enter /register.
But I am only getting a 302 redirect loop for /register.
To do so I created a RegisterViewResponse to override default behavior:
use Laravel\Fortify\Contracts\RegisterViewResponse as RegisterViewResponseContract;
class RegisterViewResponse implements RegisterViewResponseContract
{
public function toResponse($request)
{
$canEnter = true;
if($canEnter){
return redirect()->intended('/register');
} else {
return redirect()->intended("/otherPage");
}
}
}
I also added this to FortifyServiceProvider:
$this->app->singleton(RegisterViewResponse::class,Responses\RegisterViewResponse::class)
Thanks for any help or advice!

Cookie read correctly in controllers but not in middleware - Laravel

I was trying to set a cookie to define a user-preferred language. I did that by having a link that leads to a helper controller :
/set-locale/{locale}
public function edit_locale($locale) {
$durata= 2628000; // "forever"
if (Cookie::has('locale')) {
Cookie::queue(Cookie::forget('locale')); // If locale cookie is already defined, delete it
}
Cookie::queue("locale", $locale, $durata); // Set the cookie to either "en", "fr" or "ar"
return redirect()->back();
}
I know this works correctly because if I do :
dd(Cookie::get('locale'));
It shows the correct locale chosen. So next step was to actually apply this chosen locale everywhere using a middleware, I named it "SetLocale" :
public function handle(Request $request, Closure $next)
{
if (Cookie::has('locale')) {
$locale = Cookie::get('locale'); // The cookie gotten here is all scrambled for some reason
} else {
// other logic for when cookie is not set (irrelevant for this question)
}
App::setLocale($locale);
return $next($request);
}
But if I execute
dd(Cookie::get('locale'));
here in the middleware, it reads the cookie all scrambled.
So my question is why is it doing that and how do I read the cookie correctly from here?
use this to get cookie from request :
\Crypt::decrypt(Cookie::get('locale'))
or use
\Crypt::decryptString(Cookie::get('locale'))
Okay, esmaill's answer didn't work for me (Got a "unserialize(): Error at offset 0 of 43 bytes" error) but it did help point me in the right direction to solve it.
All I did was add 'locale' to the $except attribute of the EncryptCookies middleware and reset the cookie and now it's read correctly.

The most simple basic authentication in Yii2 - implementation of IdentityInterface

I would like to add HTTP basic authentication to my Yii2 application in which the username/password is stored in the Yii configuration file - for exactly one user, no DB authentication.
I have enabled authentication for my controller by adding behaviors function:
public function behaviors()
{
return [
'basicAuth' => [
'class' => \yii\filters\auth\HttpBasicAuth::className(),
'auth' => function ($username, $password) {
if ($username=='api') {
return new SimpleApiUser();
} else {
return null;
}
},
],
];
}
And I was required to create class, that implements IdentityInterface, that is why I have class:
class SimpleApiUser implements IdentityInterface {
public static function findIdentity($id)
{
return null;
}
public static function findIdentityByAccessToken($token, $type = null)
{
return null;
}
public function getId()
{
return 1;
}
public function getAuthKey()
{
return 1;
}
public function validateAuthKey($authKey)
{
return true;
}
}
That is fine, the application asks for username/password in the case of the first request, but then it managed to store the authentication somehow in some internal session and it does not required repeated authentication for each new request be it made from the browser (which my add sessions) or be it from Postman (which certainly does not keep sessions). Is it possibly to modify user class to require to provide username and password with each new request?
I've tried to play around a bit with your code.
First, your code is enough to require the basic auth to be part of every request. If the Authorization header is not present in request the yii will return 401 Unauthorized. So your implementation is already doing what you need.
There are reasons why user is not required to enter username/password each time.
For web browsers:
The credentials are saved for session and the browser will send them automatically in each subsequent request without prompting them again from user.
For postman: The authorization is stored for request as long as you don't manually remove the authorization settings it will be sent as part of each request.
If you want to force users to manually enter username/password with each request you can extend the HttpBasicAuth component to pretend that the authorization was not part of request for every other request like this
use Yii;
use yii\filters\auth\HttpBasicAuth;
class MyHttpBasicAuth extends HttpBasicAuth
{
const SESSION_KEY = 'authForced';
private $session;
public function __construct($config = [])
{
parent::__construct($config);
$this->session = Yii::$app->session;
}
public function authenticate($user, $request, $response)
{
if ($this->session->has(self::SESSION_KEY)) {
$this->session->remove(self::SESSION_KEY);
return parent::authenticate($user, $request, $response);
}
$this->session->set(self::SESSION_KEY, true);
return null;
}
}
But this will require sessions to work so it can only be used with browsers. It won't work well for API. For postman this implementation would make every other request fail with 401 Unauthorized. It would fail same way for api that will work with cookies and it would fail each request for api that wouldn't work with cookies.
Side note: The postman does keep/send cookies so sessions works with postman.

Laravel 5.3 API route not saving session between requests

I am trying to build a static HTML viewer through Laravel's 5.3 API routing logic and JWT. The files are all stored on S3 and need to be protected so I thought the best way to do this was to make a kind of proxy that all the files pass through. That way I can check the token of the user from the API request and load the files accordingly.
The first file loads fine.
http://example.com/api/proxy/file.html?token={token}
The issue arises when the HTML file tries to load files from itself. It works when I strip out the authentication functions so I know it's not an issue with getting the files. It's because the token is not appended to future requests. It sends this instead without the token.
http://example.com/api/proxy/some_image.png
I attempted to add the following code to my token checker logic.
public function __construct(JWTAuth $jwtAuth)
{
$this->middleware(function ($request, $next) use ($jwtAuth) {
if (!$jwtAuth->getToken()) {
if (!Auth::user()) {
return response()->error('The token could not be parsed from the request', 400);
} else {
$this->authUser = Auth::user();
}
} else {
$this->authUser = $jwtAuth->parseToken()->authenticate();
Auth::setUser($this->authUser);
}
return $next($request);
});
}
But for some reason this does not work. When the first .html loads up with the token it tries to authenticate the user using Laravel's Auth middleware but Auth::user() returns null on the image request.

Laravel 5 POST data to DB

i want to insert data to db using POST request
table food_directory
id (auto incremenat)
name
fructose
polylos
fructan
public function postDirec()
{
if (\Request::ajax()) {
$FodMaps = \Request::get('name');
\DB::table('food_directory')->insert([
'food_directory' => $FodMaps,
]);
}
}
Route
Route::post('postDirec', 'FodMapController#postDirec');
this will return Tokenmismatch issue.. please advice
You need to add the CSRF-token in your form, by adding this line somewhere between your form's opening and closing tag:
{!! csrf_field() !!}
Goto App\Http\Kernel.php
And comment out this line
\App\Http\Middleware\VerifyCsrfToken::class,
It should be Line 20 in that file if you haven't made any other changes.
if you want to disable csrf protection on certain routes you can to this approach.
in the app/Http/Middlewares/VerifyCsrfToken.php modify handle method to
//disable CSRF check on following routes
$skip = [
'/your-uri/you-want-to-disable-protection-for',
route('or_some_route')
];
foreach ($skip as $route) {
if ($request->is($route)) {
return $this->addCookieToResponse($request, $next($request));
}
}
return parent::handle($request, $next);
Put uri you want to disable into the skip array. It will then call the parent's class addCookieToResponse method that will set CSRF token to the cookie and request would be treated as protected.

Resources