yii2 UrlManager error with last element in url - yii2

How can I set up urlManager rules like that?
/category/category1/element/
/category2/element/
Yii perceives the last element as a category.
I need exactly this scheme url.
If you do not put the last slash, then everything is OK, but it is needed
Now i have this rules
'blog/<category:[\w_\/-]+>' => 'blog/category',
'blog/<category:[\w_\/-]+>/<slug>' => 'blog/post',
they do not work. There is an option to parse url and run needed action in controller, but its wrong

Related

Angular 6 : Checking for safe route/URL

In my Angular 6 application, I would like to check if the given route does not contain any miscellaneous cross-site scripting code like adding a javascript URL or anything which can expose critical data to a third party.
Here is the below code where I am to check if the URL is safe or not, like if the URL contains iframe or javascript injection. but this not give any flag whether it is safe or not.
let's say URL is like this.
https://localhost/MyApp/%60%22%22%3E%3Ciframe srcdoc=%22<img src=x:x onerror=alert(document.cookie)>%22%3E%3C/iframe%3E%60
// in app.component.ts
this.router.events
.filter(event => event instanceof RoutesRecognized)
.map((event: RoutesRecognized) => {
console.log("test", this._sanitizer.sanitize(SecurityContext.URL,
event.state.url));
// here I want to proceed if anything fishy here and will route to 404 page.
}
any idea here, on how to prevent such csrf/xsrf.
You can refer below links, which might be helpful to you.
Link1
Link2

Html::a doesn't link to needed module in Yii2

I'm trying to link the value to particular action, but somehow it doesn't link me to another module.
Here's the value:
'value' = ['module/controller/view', 'id' => $model->id]),
Here is the correct link into which I need to be linked:
localhost/index.php?r=module/controller/view&id=21
Here's the link in which I'm getting linked:
localhost/index.php?r=this-module%module%controller%view&id=21
As you can see somehow I'm staying in the same module and the link doesn't link me to needed module. Could someone explain me why?
You need to add slash:
['/client/entry/view', ...
Without slash it takes it as a subpage of current address.

Yii2: data-method='post' is sending GET request

I am making changes in existing web page in yii2.
I had this section of code:
Html::a('Confirm!',[
'default/apply',
'confirm' => 1,
'id' => $data->id
],['class' => 'btn-primary','data-method' => 'post'])
I have moved this to a different container on the same page.
(I had to adjust slightly, changing $data->id into $projectInfo->id as earlier it was inside anonymous function within a widget and now inside a foreach loop. But this should not be relevant I suppose.)
Both before and after the change the same line is present in html (but in different part of the page):
<a class="btn-primary" href="/participant/default/apply/13/1" data-method="post">Confirm!</a>
But on execution http request is now sent as GET instead of POST.
BEFORE: "POST /participant/default/apply/13/1 HTTP/1.1"
NOW: "GET /participant/default/apply/13/1 HTTP/1.1"
I cannot figure out why this changed and how to get the code to work as POST in new location. This href execution must depend on some additional factor that I am not aware of.
You can send POST request using link thanks to JavaScript inside yii.js file that wraps it in form silently. If this JS is not loaded in assets link works in standard way which is sending GET requests.
Check if yii.js is loaded (usually through registering yii\web\YiiAsset directly or by dependency).

Dynamic URL in Laravel 5.0

I am trying to display a specific link on all the pages in my web application. The link is given below
Some text for the link!
My routes file
Route::get('home', 'HomeController#index');
Route::get('path1/path2/path3', 'SomeController#someFunction');
Route::get('my-link', 'SomeController#myLink');
While browsing the web application, when I am at mydoamin.com/home, the link address is mydomain.com/my-link, which is correct.
But when I am at the URL mydoamin.com/path1/path2/path3, the link address becomes mydoamin.com/path1/path2/my-link. Hence, after clicking the link I get 404 error as the path doesn't exist.
How do I make the link to always show mydomain.com/my-link on all the pages without hard-coding the domain name?
Note: I have put the link code Some text for the link! in a partial file; and I am including that file in all the pages.
Why you shouldn't use /my-link?
You could use My link on a site that's running on the root directory (www.domain.com/my-link). But if you're running it in a subdirectory you need to change all the url's.
That's why Laravel introduced named routes, this will automatically creates the correct url.
For example:
If you're site runs at www.domain.com/my-website/ and you need to point to /my-link you need to change all your links in your project to /my-website/....
So I suggest to use named routes.
How to use named routes
Named routes allow the convenient generation of URLs or redirects for specific routes.
And this is de code you need to use:
Route::get('home', ['as' => 'home', 'uses' => 'HomeController#index']);
Route::get('path1/path2/path3', ['as' => 'path3', 'uses' => 'SomeController#someFunction']);
Route::get('my-link', ['as' => 'my-link', 'uses' => 'SomeController#myLink']);
After that you can use:
<a href="{{ url(route('my-link')) }}">
Some text for the link!
</a>
Laravel will automatically create the correct url for the named route you want to use.
Hope this works!
More information at https://laravel.com/docs/5.2/routing#named-routes
Should be href="/my-link", / means start from root.
You may try different ways like ./my-link ,../my-link or ../../my-link to see what happend.
see link: absolute, relative, root

Yii2: exclude specific controller actions from '$this->goBack()'

I have views from various controller actions which are solely to be run from an iframe placed in another view.
Currently, when the iframe loads, and I go to the log in page to log in, on success the login controller (using yii2 user module) calls $this->goBack(), redirecting me to the iframe source URL (since it's the last page visited), rather than the original page containing the iframe.
Basically, I'd like to exclude specific controller actions from being set as the return URL when $this->goBack() is called. Bonus points if all actions loaded in iframes are automatically excluded from $this->goBack().
Ok, I'll have a go at this! This code is totally untested! Your problem is that the action has no way of knowing whether it's been called from an iframe or not, unless you give it one. So, the basis of my attempt at an answer is that all urls for iframes should have an additional get parameter. Lets call that caller. So each iframe should look something like
<iframe url="index.php?r=controller/action&caller=this-controller/action</iframe>
Now you can always test the request url to see if it was called from an iframe. In addition, every link within the iframe should have this parameter added to it's url.
So, now we have at least two problems. Firstly, how to automatically add caller as a get parameter, without having to re-write every url, and secondly, how to reconfigure the goBack() method so it knows the difference between the two types of request.
The first problem can be relatively easily resolved by adding another view layer in between the controller and the view you want I'll call it iframe. So in your controller action, add this;
$view = 'The name of the view you want to render';
$this->render('iframe', 'view' => $view);//Add in any other parameters you want to pass
Your iframe view file should contain something like this;
<iframe src="<?php Url::to(['however you generate the url for your iframe', 'caller' => Url::to($this->context->route)]); ?>">
<?php $this->render($view); ?>//Pass additional parameters to the view if needed
</iframe>
Now we have a way of testing a controller/action call to see if it being requested by am iframe. The caller parameter is important because it allows us to extract a string to use as the value for goBack() and other methods.
Next, we need to extend UrlManager, as all request, response, Url:to() and goBack() methods and classes ultimately use the UrlManager to complete the methods for generating urls.
So, create a new UrlManager. We'll copy most of the code from the existing UrlManager, just adding some spiciness of our own. I've stored mine in commands, but put your where you like and change the namespace accordingly.
<?php
namespace app\commands;
use Yii;
use yii\web\UrlManager;
class CustomUrlManager extends UrlManager {
public function createUrl($params){
$request = Yii::$app()->request;
$caller = $request->get('caller');
if ($caller && !$params['caller']){
$params['caller'] = $caller;
}
return parent::createUrl($params);
}
}
So now, the iframe generates a caller parameter, and every link within the iframe will also have caller appended as a parameter, as long ass you've used either Url::to() (or variants on that method) or Yii::$app->UrlManager to generate your links.
Now all we need to do is customise the goBack() method of your controller to send any goBack() requests to the original source iframe.
public function goBack($defaultUrl = null)
{
$caller = Yii::$app->request->get('caller');
if ($caller){
return Yii::$app->getResponse()->redirect($caller);
}
return Yii::$app->getResponse()->redirect(Yii::$app->getUser()->getReturnUrl($defaultUrl));
}
Finally you need to configure Yii to use your new UrlManager, in your config file;
'components' => [
'urlManager' => [
'class' => 'app/commands/CustomUrlManager'
]
]
I'd love to know if this works, it's been an interesting challenge!