Laravel filesystem sftp set umask for new folders - laravel

is it possible to set a umask for new created folders
Storage::disk('sftp')->put('/path/to/folder/new/test.txt', $contents);
In my case, the used umask is 744. Is it possible to change the umask for new created folders?
Thanks in advance.

In my case, it was enough to set directoryPerm with the needed umask in the config of the sftpAdapter

You can use this function :
File::makeDirectory($path, $mode = 0777, true, true);
In your case, just change the $mode to 0774 :
Storage::disk('sftp')->makeDirectory($path, 0774);
Documentation : https://laravel.com/docs/5.1/filesystem#introduction

The solution is to use the 'directoryPerm' => 0755, key value in config. The config:
'disks' => [
'remote-sftp' => [
'driver' => 'sftp',
'host' => '222.222.222.222',
'port' => 22,
'username' => 'user',
'password' => 'password',
'visibility' => 'public', // set to public to use permPublic, or private to use permPrivate
'permPublic' => 0755, // whatever you want the public permission is, avoid 0777
'root' => '/path/to/web/directory',
'timeout' => 30,
'directoryPerm' => 0755, // whatever you want
],
],
And in the codes, class League\Flysystem\Sftp\StfpAdapter in file /private/var/www/megalobiz/vendor/league/flysystem-sftp/src/StfpAdapter , there is 2 important attributes to see clearly:
/**
* #var array
*/
protected $configurable = ['host', 'hostFingerprint', 'port', 'username', 'password', 'useAgent', 'agent', 'timeout', 'root', 'privateKey', 'passphrase', 'permPrivate', 'permPublic', 'directoryPerm', 'NetSftpConnection'];
/**
* #var int
*/
protected $directoryPerm = 0744;
The $configurable is all possible keys to configure filesystem sftp driver above. You can change directoryPerm from 0744 to 0755 in config file:
'directoryPerm' => 0755,
HOWEVER, because there is kind a like a Bug in StfpAdapter https://github.com/thephpleague/flysystem-sftp/issues/81 that won't use the $config parameter on createDir:
$filesystem = Storage::disk('remote-sftp');
$filesystem->getDriver()->getAdapter()->setDirectoryPerm(0755);
$filesystem->put('dir1/dir2/'.$filename, $contents);
Or set it with public in purpose:
$filesystem->put('dir1/dir2/'.$filename, $contents, 'public');

Related

Laravel LDAP (Adldap2) Can't authenticate,username is null into guard->attempt

Morning,
I keep getting the message "A username must be specified." when trying to login my app.
Connection to LDAP is OK, sync also, in my database/table users i see all username with password.
But can't login with anyone username.
Trying to dd($username) into LoginController, "guard()->attempt" show me "null".
Thanks for your help !
My version
Laravel Version: ^7.0
Adldap2-Laravel Version: ^6.1
PHP Version: ^7.2.5
LDAP Type: OpenLDAP
my .env
LDAP_HOSTS=ldap.forumsys.com
LDAP_BASE_DN=dc=example,dc=com
LDAP_USERNAME=cn=read-only-admin,dc=example,dc=com
LDAP_PASSWORD=password
LDAP_PASSWORD_SYNC=true
my ldap.php
<?php
return [
'logging' => env('LDAP_LOGGING', false),
'connections' => [
'default' => [
'auto_connect' => env('LDAP_AUTO_CONNECT', true),
'connection' => Adldap\Connections\Ldap::class,
'settings' => [
'schema' => Adldap\Schemas\OpenLDAP::class,
'account_prefix' => env('LDAP_ACCOUNT_PREFIX', ''),
'account_suffix' => env('LDAP_ACCOUNT_SUFFIX', ''),
'hosts' => explode(' ', env('LDAP_HOSTS', 'corp-dc1.corp.acme.org corp-dc2.corp.acme.org')),
'port' => env('LDAP_PORT', 389),
'timeout' => env('LDAP_TIMEOUT', 5),
'base_dn' => env('LDAP_BASE_DN', 'dc=corp,dc=acme,dc=org'),
'username' => env('LDAP_USERNAME', 'username'),
'password' => env('LDAP_PASSWORD', 'secret'),
'follow_referrals' => false,
'use_ssl' => env('LDAP_USE_SSL', false),
'use_tls' => env('LDAP_USE_TLS', false),
],
],
],
];
my ldap_auth
<?php
return [
'connection' => env('LDAP_CONNECTION', 'default'),
'provider' => Adldap\Laravel\Auth\DatabaseUserProvider::class,
'model' => App\User::class,
'rules' => [
// Denys deleted users from authenticating.
Adldap\Laravel\Validation\Rules\DenyTrashed::class,
// Allows only manually imported users to authenticate.
// Adldap\Laravel\Validation\Rules\OnlyImported::class,
],
'scopes' => [
// Only allows users with a user principal name to authenticate.
// Suitable when using ActiveDirectory.
// Adldap\Laravel\Scopes\UpnScope::class,
// Only allows users with a uid to authenticate.
// Suitable when using OpenLDAP.
// Adldap\Laravel\Scopes\UidScope::class,
],
'identifiers' => [
'ldap' => [
'locate_users_by' => 'uid',
'bind_users_by' => 'distinguishedname',
],
'database' => [
'guid_column' => 'objectguid',
'username_column' => 'username', //'email',
],
'windows' => [
'locate_users_by' => 'samaccountname',
'server_key' => 'AUTH_USER',
],
],
'passwords' => [
'sync' => env('LDAP_PASSWORD_SYNC', false),
'column' => 'password',
],
'login_fallback' => env('LDAP_LOGIN_FALLBACK', false),
'sync_attributes' => [
//'email' => 'userprincipalname',
'username' => 'uid',
'name' => 'cn',
],
'logging' => [
'enabled' => env('LDAP_LOGGING', true),
'events' => [
\Adldap\Laravel\Events\Importing::class => \Adldap\Laravel\Listeners\LogImport::class,
\Adldap\Laravel\Events\Synchronized::class => \Adldap\Laravel\Listeners\LogSynchronized::class,
\Adldap\Laravel\Events\Synchronizing::class => \Adldap\Laravel\Listeners\LogSynchronizing::class,
\Adldap\Laravel\Events\Authenticated::class => \Adldap\Laravel\Listeners\LogAuthenticated::class,
\Adldap\Laravel\Events\Authenticating::class => \Adldap\Laravel\Listeners\LogAuthentication::class,
\Adldap\Laravel\Events\AuthenticationFailed::class => \Adldap\Laravel\Listeners\LogAuthenticationFailure::class,
\Adldap\Laravel\Events\AuthenticationRejected::class => \Adldap\Laravel\Listeners\LogAuthenticationRejection::class,
\Adldap\Laravel\Events\AuthenticationSuccessful::class => \Adldap\Laravel\Listeners\LogAuthenticationSuccess::class,
\Adldap\Laravel\Events\DiscoveredWithCredentials::class => \Adldap\Laravel\Listeners\LogDiscovery::class,
\Adldap\Laravel\Events\AuthenticatedWithWindows::class => \Adldap\Laravel\Listeners\LogWindowsAuth::class,
\Adldap\Laravel\Events\AuthenticatedModelTrashed::class => \Adldap\Laravel\Listeners\LogTrashedModel::class,
],
],
];
my loginController
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
public function username()
{
return 'username';
}
}
Been through this pain myself.
It looks like you are connecting to LDAP with your service account, but I don't see where you are logging the authenticated user into Laravel. Do your users have to supply a username and password on a screen somewhere? If not, how do you grab the user and log them in to Laravel?
The way I did this in the businesses that had to go through LDAP was to have the normal Laravel login page, but a middle method within the login controller which sent a message to LDAP through the service account with the PW. If this succeeded, then login with Laravel's standard method. Basically just check the PW against LDAP and then log in rather than checking against the Laravel DB.
Example code - this will vary wildly but can give you an idea of what might work:
if(env('LOGIN', false) === 'LDAP'){
$ldap = new \App\Http\Controllers\ClientSpecific\BaseLDAPController();
$username = $request->input('username');
if($ldap->authenticate($username, $request->input('password'))){
return $this->sendLoginResponse($request);
}
}else {
if ($this->guard()->attempt($credentials, $request->has('remember'))) {
return $this->sendLoginResponse($request);
}
}
I know this is an old question, but I was still facing this issue even in 2020 and it took a lot of my time. Actually the problem is very silly if you are also trying to bind an OpenLDAP server with your Laravel application using Adldap2-Laravel package.
Adldap2-Laravel is by default configured for Microsoft's Active Directory. But for OpenLDAP, we need to properly change the Identifiers array as follows..
<?php
return [
// configurations settings...
'identifiers' => [
'ldap' => [
'locate_users_by' => 'uid', // changed from userprincipalname
'bind_users_by' => 'dn', // changed from distinguishedname
],
'database' => [
'guid_column' => 'objectguid',
'username_column' => 'username', //'email',
],
'windows' => [
'locate_users_by' => 'samaccountname',
'server_key' => 'AUTH_USER',
],
],
// rest of the configurations...
];
Do tell me if my answer is not clear for new comers since I'm also a newbie. I'll try to explain the solution further better :)

No such file, Storing file into the local storage is not working on production

I have a laravel application deployed on Elasticbeanstalk, I'm working on a feature where I need to get a zip file from s3 bucket, store it into the local storage in order to be able to use laravel-zip to remove a pdf file from that zip.
the code is working locally, but I'm receiving 'No Such file error' after testing on production:
// get the file from s3 and store it into local storage
$contents = Storage::disk('s3')->get($file_name);
$zip_local_name = 'my_file.zip';
Storage::disk('local')->put($zip_local_name, $contents);
// use laravel-zip to remove the unwanted pdf file from the result
$manager = new ZipManager();
$file_path = storage_path('app').'\\'.$zip_local_name; // register existing zips
$manager->addZip(Zip::open($file_path));
$zip = $manager->getZip(0);
$zip->delete($data["Iso_Bus"]["field_name"].'.pdf');
$zip->close();
I made sure that the file exists on s3, so I think my main problem is that the file is not stored in the local storage.
Any help is appreciated
Edit filesystems configrations:
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => '***',
'secret' => '***',
'region' => '***',
'bucket' => '****',
'url' => '****',
],
],
You're getting full path for the file wrongly, try this one instead:
$file_path = Storage::disk('local')->path($zip_local_name);
Note: It's better to check if the Storage::put was successful before continue:
// get the file from s3 and store it into local storage
$contents = Storage::disk('s3')->get($file_name);
$zip_local_name = 'my_file.zip';
if (Storage::disk('local')->put($zip_local_name, $contents)) {
// `Storage::put` returns `true` on success, `false` on failure.
// use laravel-zip to remove the unwanted pdf file from the result
$manager = new ZipManager();
$file_path = $file_path = Storage::disk('local')->path($zip_local_name);
$manager->addZip(Zip::open($file_path));
$zip = $manager->getZip(0);
$zip->delete($data["Iso_Bus"]["field_name"].'.pdf');
$zip->close();
}

Laravel Storage SFTP and uploaded files permissions

I'm using Storage:SFTP (league/flysystem-sftp) to upload some files to an external server. Everything goes fine with a small issue: the files are uploaded with a 0644 (-rw-r--r--) permission. I've tried to use 'public' option on the put method as the example from docs, like
Storage::disk('remote-sftp')->put($filename, $contents, 'public');
but if fails returning FALSE and doesn't uploads the file.
If I remove the 'public' parameter, everything goes well but with the wrong permissions for file.
Is there any way to set the uploaded file permissions to something like 0666?
Finally the solution was a combination of Alpy's answer and configuration.
Calling setVisibility() went without failure, but keep permissions in 0644. Digging into the FTP/SFTP driver found that the 'public' permission has a pattern that can be assigned in config using 'permPublic' key, so writting in config/filesystems.php the desired octal permission it worked as spected.
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
'remote-sftp' => [
'driver' => 'sftp',
'host' => '222.222.222.222',
'username' => 'myuser',
'password' => 'mypassword',
'visibility' => 'public',
'permPublic' => 0766, /// <- this one did the trick
// 'port' => 22,
'root' => '/home',
// 'timeout' => 30,
],
],
];
File permissions are based on two factors. Visibility and Permissions. You can set these two options in the driver config as such:
'remote' => [
'driver' => 'sftp',
'host' => 'hostname',
'root' => '/',
'username' => 'user',
'password' => env('SYSTEM_PASS'),
'visibility' => 'public', // defaults to 'private'
'permPublic' => 0775
]
The permissions are set based on the visibility. So if you set 'permPublic' and don't set 'visibility' nothing will change as, the setVisibility() function uses 'visibility' to get the permissions.
vendor/league/flysystem-sftp/src/SftpAdapter.php
public function setVisibility($path, $visibility)
{
$visibility = ucfirst($visibility);
// We're looking for either permPublic or permPrivate
if (! isset($this->{'perm'.$visibility})) {
throw new InvalidArgumentException('Unknown visibility: '.$visibility);
}
$connection = $this->getConnection();
return $connection->chmod($this->{'perm'.$visibility}, $path);
}
The public default is 0755.
The private default is 0700.
umask
If 'visibility' is not set, I believe the permissions are set based on the remote system user's umask. You are able to modify this on the remote system, if you so choose. set umask for user
Directories
One thing to note while working with permissions is that this will only affect created files. To set the permissions on created directories, use the 'directoryPerm' attribute in your config.
This defaults to 0744
Here is a more global and efficient solution. I needed to control permission on Files and also directories when saving a file under recursive directories.
League SftpAdapter is creating the directories recursively if not exist yet. But the main problem is that, it won't add the permPublic => 0755 for directories, but only files, hence www-data user end up to have no access to the file if it's inside of a newly created directory. The solution is to dive in the code to see what's happening:
'disks' => [
'remote-sftp' => [
'driver' => 'sftp',
'host' => '222.222.222.222',
'port' => 22,
'username' => 'user',
'password' => 'password',
'visibility' => 'public', // set to public to use permPublic, or private to use permPrivate
'permPublic' => 0755, // whatever you want the public permission is, avoid 0777
'root' => '/path/to/web/directory',
'timeout' => 30,
'directoryPerm' => 0755, // whatever you want
],
],
In League\Flysystem\Sftp\StfpAdapter, there is 2 important attributes to see clearly:
/**
* #var array
*/
protected $configurable = ['host', 'hostFingerprint', 'port', 'username', 'password', 'useAgent', 'agent', 'timeout', 'root', 'privateKey', 'passphrase', 'permPrivate', 'permPublic', 'directoryPerm', 'NetSftpConnection'];
/**
* #var int
*/
protected $directoryPerm = 0744;
The $configurable is all possible keys to configure filesystem sftp driver above. You can change directoryPerm from 0744 to 0755 in config file:
'directoryPerm' => 0755,
HOWEVER, because there is kind a like a Bug in StfpAdapter https://github.com/thephpleague/flysystem-sftp/issues/81 that won't use the $config parameter on createDir:
$filesystem = Storage::disk('remote-sftp');
$filesystem->getDriver()->getAdapter()->setDirectoryPerm(0755);
$filesystem->put('dir1/dir2/'.$filename, $contents);
Or set it with public in purpose:
$filesystem->put('dir1/dir2/'.$filename, $contents, 'public');
I found this while looking for a solution and I think I've found what works in Laravel 9 after digging through the flysystem code.
Adding the following settings to my config looks to have done the trick.
'visibility' => 'public',
'permissions' => [
'file' => [
'public' => 0664,
'private' => 0664,
],
'dir' => [
'public' => 0775,
'private' => 0775,
],
],
Please try this:
Storage::disk('remote-sftp')->put($filename, $contents)->setVisibility( $filename, 'public');
assuming the filename is also having the path..
Storage::disk('sftp')->download(...

Laravel download not working

In my application I have the need to:
upload a file
store information in the db
store the file in a local or remote filesystem
listing all the db rows with a link to download the file
remove the file from the db and from the filesystem
I am trying to develop the 4th but the solutions found here and here don't work for me.
My filesystem.php is:
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'visibility' => 'public',
],
'myftpsite' => [
'driver' => 'ftp',
'host' => 'myhost',
'username' => 'ftpuser,
'password' => 'ftppwd',
// Optional FTP Settings...
// 'port' => 21,
'root' => '/WRK/FILE/TEST',
// 'passive' => true,
// 'ssl' => true,
// 'timeout' => 30,
],
In the Controller I store the file with:
... validation here ...
$path = $request->uploadfile->storeAs('', $request->uploadfile->getClientOriginalName(), self::STORAGEDISK);
$file = new TESTFile;
... db code here ...
$file->save();
At this point I would like to retrive the variable to pass to the download methods (url or path of my file). I found 2 ways
Storage::url($pspfile->filename) *return* **/storage/** accept.png
Storage::disk(self::STORAGEDISK)->getDriver()->getAdapter()->applyPathPrefix($pspfile->filename) *return* C:\xampp\htdocs\myLaravel\ **storage** \app\accept.png
Any help or suggestion to do it in a better way will be very appreciated.
EDIT
For the moment I separete local/public from FTP.
The download is working if in the Controller I modify
$path = $request->uploadfile->storeAs('',
$request->uploadfile->getClientOriginalName()
,self::STORAGEDISK);
$file->fullpath = $path;
with
$file->fullpath = storage_path('app\\') . $path;
where 'app\' is the storage_path configured as root in filesystem.php
Moreover I can avoid to hardcode and use
$file->fullpath = Storage::disk(self::STORAGEDISK)
->getDriver()
->getAdapter()
->getPathPrefix() . $path;
In this way the download method can use
return response()->download($pspfile->fullpath);
I am still looking for a way to retrive a valid scr attribute for an img tag.
In addition I would like the same with remote stored files (maybe with local temp dir and file?)
I made something similar some time ago. Maybe this example code helps you.
class FileController extends Controller
{
// ... other functions ...
public function download(File $file)
{
if (Storage::disk('public')->exists($file->path)) {
return response()->download(public_path('storage/' . $file->path), $file->name);
} else {
return back();
}
}
public function upload()
{
$this->validate(request(), [
'file-upload' => 'required|file',
]);
$path = request()->file('file-upload')->store('uploads', 'public');
$file = new File;
$file->name = request()->file('file-upload')->getClientOriginalName();
$file->path = $path;
$file->save();
return back();
}
}

yii2 Unable to verify your data submission

I use nginx, PHP 5.5.14, php-fpm, yii2, mac os.
I changed yii config to store session in database (postgress, user is superuser).
This is in my config:
'session' => [
'class' => 'yii\web\DbSession',
'sessionTable' => 'session',
],
And now when I try to register new user I've got this error:
Bad Request (#400)
Unable to verify your data submission
Here is a part of log:
10 17:25:57.434 info yii\db\Command::query SELECT "data" FROM "session" WHERE "expire">1425993957 AND "id"='cfg9sutufqchr1tdose4cack15'
/Users/pupadupa/Dev/www/mint-office-web/components/Controller.php (41)
11 17:25:57.442 info yii\web\Session::open Session started
/Users/pupadupa/Dev/www/mint-office-web/components/Controller.php (41)
12 17:25:57.450 error yii\web\HttpException:400 exception 'yii\web\BadRequestHttpException' with message 'Не удалось проверить переданные данные.' in /Users/pupadupa/Dev/www/mint-office-web/vendor/yiisoft/yii2/web/Controller.php:110
Stack trace:
#0 /Users/pupadupa/Dev/www/mint-office-web/components/Controller.php(41): yii\web\Controller->beforeAction(Object(app\controllers\user\RegistrationAction))
#1 /Users/pupadupa/Dev/www/mint-office-web/vendor/yiisoft/yii2/base/Controller.php(149): app\components\Controller->beforeAction(Object(app\controllers\user\RegistrationAction))
#2 /Users/pupadupa/Dev/www/mint-office-web/vendor/yiisoft/yii2/base/Module.php(455): yii\base\Controller->runAction('registration', Array)
#3 /Users/pupadupa/Dev/www/mint-office-web/vendor/yiisoft/yii2/web/Application.php(83): yii\base\Module->runAction('user/registrati...', Array)
#4 /Users/pupadupa/Dev/www/mint-office-web/vendor/yiisoft/yii2/base/Application.php(375): yii\web\Application->handleRequest(Object(yii\web\Request))
#5 /Users/pupadupa/Dev/www/mint-office-web/web/index.php(20): yii\base\Application->run()
#6 {main}
13 17:25:57.454 trace yii\base\Controller::runAction Route to run: index/error
BTW,
I've got <?= Html::csrfMetaTags() ?> in head section and I have csrf input in my form. So it seems not the problem
I don't want to do public $enableCsrfValidation = false; because I think it's not solution but workaround.
How could I understand what cause this error?
As I mentioned earlier problem only appears when I store session in database.
Some additional information:
I could set and get variable from session. For example, I put it in beoreAction of Controller.php
Yii::$app->session->set('test', 'qwe');
$t = Yii::$app->session->get('test') ;
var_dump($t);
But after that If I comment first line like this
//Yii::$app->session->set('test', 'qwe');
$t = Yii::$app->session->get('test') ;
var_dump($t);
and refresh the page - I recieve NULL (BTW I could see Cookie:PHPSESSID=cfg9sutufqchr1tdose4cack15 in cookies after refresh).
So it seems there are some problems with session (DbSession) or maybe my php/php-fpm/nginx settings.
My UserController.php:
<?php
namespace app\controllers;
use app\components\Controller;
use app\models\Client;
use app\models\User;
use yii\filters\AccessControl;
use yii\web\BadRequestHttpException;
use yii\web\NotFoundHttpException;
class UserController extends Controller
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout', 'employee'],
'rules' => [
[
'actions' => ['logout',],
'allow' => true,
'roles' => ['#'],
],
[
'actions' => ['employee', 'employee_add'],
'allow' => true,
'roles' => [ROLE_CLIENT_ADMIN],
],
],
],
];
}
public function actions()
{
return [
'login' => 'app\controllers\user\LoginAction',
'logout' => 'app\controllers\user\LogoutAction',
'restore' => 'app\controllers\user\RestoreAction',
'registration' => 'app\controllers\user\RegistrationAction',
'employee' => 'app\controllers\user\EmployeeAction',
'employee_add' => 'app\controllers\user\EmployeeAddAction',
//'passwd' => 'app\controllers\user\PasswdAction',
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV === 'dev' ? 'testme' : null,
],
];
}
/**
* #param int $clientId
* #return Client
* #throws BadRequestHttpException
* #throws NotFoundHttpException
*/
public function getClient($clientId)
{
if (!\Yii::$app->user->can(ROLE_ADMIN)) {
/* #var User $user */
$user = \Yii::$app->user->identity;
$clientId = $user->client_id;
}
if (!$clientId) {
throw new BadRequestHttpException('Bad request');
}
$client = Client::find()->where(['id' => $clientId])->one();
if (!$client) {
throw new NotFoundHttpException('Компания не найдена');
}
return $client;
}
}
My RegistrationAction.php:
<?php
namespace app\controllers\user;
use app\models\UserConfirm;
use Yii;
use app\components\Action;
use app\forms\RegistrationForm;
use yii\web\NotFoundHttpException;
class RegistrationAction extends Action
{
public function run($key = null)
{
if ($key !== null) {
/* #var UserConfirm $confirm */
$confirm = UserConfirm::find()->andWhere('expire > NOW()')->andWhere([
'key' => $key,
'action' => 'reg'
])->one();
if (!$confirm) {
throw new NotFoundHttpException('Key not found');
}
$user = $confirm->user;
$user->enabled = true;
$user->last_login = date('Y-m-d H:i:s');
$user->save();
$confirm->delete();
Yii::$app->user->login($user, 0);
return $this->controller->goHome();
}
$model = new RegistrationForm();
if ($model->load($_POST) && $model->validate() && $model->register()) {
$subject = Yii::$app->name . ' - Success';
$message = $this->controller->renderPartial(
'//email/registration',
[
'username' => $model->email,
'password' => $model->password,
'key' => $model->key,
'keyExpire' => $model->keyExpire
]
);
$res = Yii::$app->mailer->compose()
->setTo($model->email)
->setFrom([Yii::$app->params['from'] => Yii::$app->params['fromName']])
->setSubject($subject)
->setHtmlBody($message)
->send();
Yii::$app->session->setFlash('registrationFormSubmitted');
return $this->controller->refresh();
}
return $this->controller->render('registration', ['model' => $model]);
}
}
Looks like your session id changes. Check if the value of the session cookie changes after a second request. This happens when you misconfigure the domain that is set for the session cookie, make sure it matches the hostname in your URL.
I think this happens atimes when the server is messed up, all I needed to do was to restart my apache server.
For apache on MacOSx
sudo apachectl restart
For apache on Linux
sudo service apache2 restart
or
sudo service httpd restart
i hv used this while calling logout
$menuItems[] = [
'label' => 'Logout (' . Yii::$app->user->identity->username . ')',
'url' => ['/site/logout'],
// 'linkOptions' => ['data-method' => 'get']
'data-method' => 'get'
];
in main .php change post to get
---------------------------------------------------
and have changes this also
$url = Html::a('Logout',
['/site/logout'],
['class' => 'btn btn-success', 'data-method' => 'get']);
this is also in main.php
--------------------------------------------------------------------
in behaviour of site controller also
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout', 'signup','index'],
'rules' => [
[
'actions' => ['signup'],
'allow' => true,
'roles' => ['?'],
],
[
'actions' => ['logout','index'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['get'],
],
],
];
}
change post to get...and it will work....
What I did is, I just make the "csrfParam" different for both backend and frontend and after "php init" command everything is now working fine.
Not sure whether its a bug or we must have to set different "csrfParam" in case if we use DBsession.
Not sure if it's late, but I found this solution which worked for me in a similar case of Yii2 framework spitting 400 Bad Request at POST form requests.
Simply add this code in your form to manually include a CSRF input field for the key and Yii2 will accept the data submission:
<?php
use Yii;
echo Html::tag('input', '', ['type' => 'hidden', 'name' => '_csrf-backend', 'value' => Yii::$app->request->getCsrfToken()]);
?>
Note: this is for the advanced template. In the long run I suggest not to use a framework that bases on short tags as PHPers would know its a curse.

Resources