Assume I have a site with a unique URL for users, e.g. abc.com/user1.
I want users to be able to create their own user urls like abc.com/user1 to abc.com/foo
The problem here is that my site has static pages such as: about, help, contact, download.
On the profile page, when users change their url, i apply this validator to their new profile url:
'username' => 'required|alpha_dash|max:20|min:3|unique:users'
In this situation, if the user chooses their new profile url to the same as a Route of my app (help, about, download...), their URL looks like: abc.com/about, this is troublesome.
Of course, the Validator will return true because that name is valid: min=3, max=20 and unique in "users" table ( "users" table not contains any control, of course).
To solve this, I add name of some Route to "users" table (about,contact,download...), so they cannot make their profile URL like abc.com/about,
But this is not good idea, because I might add more Routes in future.
PS: I dont like URL like abc.com/profile/user1, must be abc.com/user1.
Please help me to solve this.
You can use Route::getRoutes() to get all registered routes in your application
$routes = Route::getRoutes();
foreach($routes as $route){
echo $route->getUri(); // getUri will return the url pattern it matches
}
Now you can use this to check if the username doesn't appear in your routes.
But be careful! If you want to add routes in when the application is running you will have to check everytime that there's no user that has taken the name you want to chose.
Here are some possibilities
1. Call static page routes first
You can either call the static routes first and then at the end you do a catchall like lukasgeiter suggested, or you might even do a check in the controller and go through your static pages first. The problem here is that the user can create the user (e.g. "about") but then when they call that page, they would see the about page, even though they've correctly created the username, this might create a confusion.
2. Blacklist
Another way would be to create a blacklist for these usernames, so that people can't even register these types of usernames (this would be similar to your solution of pre-creating those usernames, but this way would be a bit cleaner and more easily expandable). Using this you will always have the trouble that someone will have used the username, once you want to use it as a static page. E.g. when you want to expand into another country.
3. Static pages on one level lower
E.g. you can create the static pages one level lower, such as abc.com/static/about, so there would be no clash.
4. Prepend character before username
This is the way I went, because the other ways were technically a bit too risky for me. So I chose the '#' sign for my users. So abc.com/#ThisIsMe is my current solution. It works in different languages (as opposed to abc.com/profile/thisisme would only work in languages, where profile is the correct term)
I think Flickr went from flickr.com/username to flickr.com/photos/username. Google+ doesn't really let you decide, but makes suggestions (AND adds the +). Twitter and Facebook let users choose their own, I would assume they have a blacklist. LinkedIn uses /in/.
Related
This project is something like a social networking site built on codeigniter.
Here my default controller is MyController.php (which loads the login page)
and say my domain is aravind.com
In my application each user will have a unique id.
and what my requirement is, the particular page of the user should get opened when
the unique_id of the user is given immedetily after the domain name.
ie, aravind.com/123 should open the user page whose unique id is 123.
I know this can be acheived by placing a controller and a function in between the
domain and the unique_id, (like : aravind.com/Search_class/search_func/123).
But by doing so the url of the particular user becomes lengthy which is not acceptable.
So I require a logic to sort this issue.
Note:
I have other classes and folders in my controller package, SO the required soln should be
wise enough to diferentiate my classes and folders in the controller package with the UniqueID.
So for differentiating I can say like the classes and folder name will be of continuous String
Where UniqueID starts with an underscore (_).
The same thing is done in facebook, like if we type facebook.com/aravind.pillai.983, it will open my account,
where as if the url goes like facebook.com/settings it will open the settings page for
the user who have an active session.
Set route["404_override"] to one of your custom class (say Search.php).
So wheneven a user tries to enter with an invalid url it will be redirected to Search.php.
Here using $this->uri->segment(1) you will get the value of the first uri segment.
You can write a logic there to identify whether the user entered a valid unique_id or not.
Now you got the uri value in one class (Search.php).
You should use routing where you can set every routes you want. In APPPATH.'config/routes.php' file add this:
$route['(:any)'] = 'Search_class/search_func/$1';
You should read documentation about routing and check other examples.
Also, pay attention that application will always check for Search_class/search_func/$1 in first URI segment so you need to put this rule at the end of routes.php file. Before that rule you need to set other rules like:
$route['about'] = 'pages_c/show/about';
$route['contact'] = 'pages_c/show/contact';
// then after all declared routes, you can set wild card placeholder
$route['(:any)'] = 'Search_class/search_func/$1';
I have an Asp.net Core application I want to be able to allow multiple/ different Tenant(Client)to access the same application but using different url's. I have common database for all tenant(client).
So It is the main part I want to host my application in a domain say... www.myapplication.com then allow different Tenant(client) to access the same application using
1.www.TenantOne.myapplication.com
2.www.TenanatTwo.myapplication.com.
3.www.{TENANCY_NAME}.myapplication.com
I can't find any info on how to do this and I'm stuck.
How to do it? Please provide the code. Thanks.
As Saravanan suggested these types of questions don't belong here on SO. To get you started, I suggest you start looking if there are any frameworks such as SaaSKit available to add a multi tenancy layer to the pipeline.
The essential part is to know where each request comes from. Using subdomains is a good way to achieve that and middleware is a good place to 'identify' your tenant. You could have a database to persist the tenants but the implementation is entirely up to you. I also wrote a little article on the subject. Although it isn't ASP.NET Core, the principles still apply.
The approach I believe you are looking for is similar to the article at the url below.
https://dotnetthoughts.net/building-multi-tenant-web-apps-with-aspnet-core/
In it, the author splits the requesting URL into an array of strings delimited by the dot in the address. The variable 'subdomain' is then set to the first element of that array. In your question, it looks like you may want to use the second element in the array, but you get the idea.
var fullAddress = actionExecutingContext.HttpContext?.Request?
.Headers?["Host"].ToString()?.Split('.');
var subdomain = fullAddress[0];
//do something, get something, return something
How you use this data is up to you. The author of the article created a filter attribute, but there are many possibilities such as passing the tenant name as a parameter to a service function.
Sorry,you have to get something to start with and then come back for the people to help you with.
I would say that this is all of a domain based wild card mapping and change in your authentication logic to get the tenant id from the URL. Once you identified the tenant, you just login and then take it forward. Like you might be having a database with the tenant details like
tenant1 | tenant1.company.com | guid-ofthe-tenant | etc...
Once you get the URL, you lookup in the above table and get the tenant code and then you choose the login mode and then proceed.
In case you have tried something yet, we would be happy to point you if it does not work yet.
I'm just getting started with Apiary and I can't tell if this is a limitation of the product or just me not understanding what to do.
I'm documenting an API which authenticates the user as part of every request. Sometimes the authentication is part of the path (a request for the user's profile would have the user id in the path), other times just as parameters (?user_id=1&auth=secret), and for POST requests, part of the incoming body as JSON.
Also, there are 3 methods of authentication in the app. You can log in with a Facebook UID, email address, or using the unique id of the device you're using. The result is something that looks like this:
##User [/user/{facebook_uid}{?access_token}, /user/{email}{?device_id}, /users/{device_auth_id}{?device_id}]
This works fine, and displays in the API as I'd expect:
But this introduces 2 issues:
1) If I wanted to add a set of parameters shared by all authentication methods, I would need to add it to all 3 like this:
## User [/user/{facebook_uid}{?access_token, extra_thing, this_too},
/user/{email}{?device_id, extra_thing, this_too},
/users/{device_auth_id}{?device_id, extra_thing, this_too}]
This seems a bit messy, it'd be much nicer to apply shared parameters at the end of the path array so they apply to all, something like this:
## User [/user/{facebook_uid}{?access_token}, /user/{email}{?device_id}, /users/{device_auth_id}{?device_id}]{&extra_thing, this_too}
But this doesn't work. Is there a way to do this? The documentation wasn't very helpful with more complicated stuff like this.
Also, would there be a way to create some kind of template which I could apply to all my methods? In the case where the authentication is part of the path its a bit unavoidable, but for other requests it would be nice to just do something like include: authentication and have it pull the unique_id/auth combo from a defined template somewhere.
Thanks!
First, there isn't really support for having a single model with multiple resource representations. It is an unusual thing to do and is actually good food for thought.
Second, using multiple URIs in [path segment] is probably going to confuse Apiary's mock server and make it unusable.
In my opinion, I'd split this into three models: Facebook User, E-mail User and Device User, with slightly different documentation (how are they created? Can you really create all of them through api? etc. etc.)
It also depends on how you want to document this. As path segments are not validated (it would be strange to have different resources based on the type of the arguments), you can just have (and I'd personally do just that)
## User [/user/{id}{?access_token, extra_thing, this_too}]
+ Parameters
+ id (required, string, `test#example.com`)...id of the user. Can be either user's e-mail, facebook id or device id from where user was created.
As for reusable parts, this is currently being implemented with authentication being part of that.
I've been through a few similar posts,
Facebook Like Custom Profile URL PHP
Custom URL / Apache URL Rewriting
But its still not clear, the actual method/process is not available..
Guys , little more guidance would do a lot..
I would like to put forward the questions here:
Users should have a chance to decide what is their url, Just like in case of fb, twitter
for example: www.facebook.com/harry.inaction
I am using the linux, apache, mysql, php environment for this.
Users are identified based on their user id's which get created automatically when they join in
And I fail at the very first step, seriously I don't know get started.
Thanks
It's going to be impossible to put any details as an answer because you've got to build this system of yours and there's more than one way to do it. Design decisions will need to be made based on the way you want things to work and what you already have (they're going to have to work together in some way).
Say you've already got a system for creating users (and it sounds like you do) and you already have a system for viewing profiles. You'll need to extend this system so that you store an extra "my_vanity_url" field in your user table in your database. This field needs to be unique. When a user edits their profile, they have the option of changing this to whatever they want (limiting it to only letters and numbers and dashes for simplicity).
Next, when you display this profile, say it is via /profile.php, your code needs to check a few things.
First it needs to check how it's called, looking at $_SERVER['REQUEST_URI'] you can see either /user/some-vanity-name or /profile.php?u=1234.
If it's the latter, you need to redirect the browser, do a database lookup to see who the user with user_id 1234 is.
Pull the "my_vanity_url" column out of the database for this user and redirect the browser to /user/my_vanity_url_value (replacing my_vanity_url_value with the value of that column).
So now, if you go to http://your.domain.com/profile.php?u=1234, your browser gets redirected and the URL address bar will say http://your.domian.com/user/my_name.
Next, you need to be able to take that unique name and turn it back into the old ugly looking profile page. Two things need to happen here:
You need to extend your profile.php once more to take an optional vanity name as opposed to a user_id
You need to use mod_rewrite to internally route vanity names to /profile.php
For the first thing, you simply look for a different $_GET[] parameter instead of whatever it is for a user_id. Say it's called name: so look at $_GET['name'], see if it exists, if it does lookup the user in the user table whose vanity url name is $_GET['name']. Return the profile of that user.
For the second thing, you just need to put this in the appropriate place in your htaccess file in your document root:
RewriteEngine On
RewriteRule ^/?user/([A-Za-z0-9-]+)/?$ /profile.php?name=$1 [L]
This is just an example for how to implement something like this. It may be completely inapplicable for what you have, but it should give you an idea of what you need to do.
I have an AREA setup in my project. I need to make the routes for the area progressive, meaning that the route will build on each other.
I'm looking at this as something like a link list. Each node in the list will have a reference to a parent. As move from left to right in the list it builds, and from right to left it removes.
In the area, I have companies and that have contacts, and child companies.
For example, I have companies that would have the following:
/Companies/list
/Company/{Id}
/Company/{id}/add
/Company/{id}/edit
/Company/{id}/delete
For the contact section I need to create the following routes:
/Company/{id}/contacts/list
/Company/{id}/contact/{id}/add
/Company/{id}/contact/{id}/edit
/Company/{id}/contact/{id}/delete
How do I make sure that /Company/{id} is always in the Contact and Child Company sections of the route?
I hope that I have made my question clear.
Subjective Generalities (take with a pinch of salt):
First off, you are using Company (singular) for companies, but then you are using contacts (plural) for the contacts. There is nothing wrong with this, from a structural point of view, but your users will thank you if you are consistent with your pluralizations. I would use the plural in both cases, but that is just my preference... it looks more like English.
You also use lower case for contacts, but upper case for Company. Doesn't look professional.
The next thing that is confusing is that you are using two {id} parameters, one for companies, one for contacts. I presume these are the ids for Company and Contacts respectively. But I am confused, but being human, I am able to deduce context unlike a computer. So you would be better of specifying the parameters in your routes. Ie:
/Companies/{CompanyId}/Contacts/{ContactId}/[action]
Answering your Question with an Example:
I get the feel you don't understand routes properly. If you did, your question would be more specific.
Your route parameters can come from a number of sources, depending on how the route is requested.
You could hard code it into a link. Or, more usefully, your route registration would be designed to catch requests that map to your Action signatures.
For example, I have an eLearning app with tutors, pupils, courses and steps (ie, the steps are like sections of a course, the pupil advances through the course step by step)
The route registration looks something like:
Route or Area Registration:
context.MapRoute(
"StepDisplay",
"Course/{CourseId}/Step/{StepOrder}/Pupil/{PupilName}/{TutorName}",
new { controller = "Course", action = "Display", TutorName = UrlParameter.Optional },
new[] { "ES.eLearningFE.Areas.Courses.Controllers" }
);
This route will catch a request from the following ActionLink:
ActionLink in View:
#Html.ActionLink(#StepTitle, MVC.Courses.Course.Actions.Display(Model.CourseId, step.StepOrder, Model.Pupil.UserName, tutorName))
Now, I just need to show you the Display action's signature:
CoursesController:
public virtual ActionResult Display(int CourseId, int StepOrder, string PupilName, string TutorName)
There are a few things to note here:
That I am able to call this specific route by giving the user a link to click on.
I construct this link using the Html.ActionLink helper
I have used David Ebbo's t4mvc nuget package so that I can specify the action I am calling and its parameters. By which I mean specifying the ActionResult parameter of the Html.ActionLink helper using:
MVC.Courses.Course.Actions.Display(Model.CourseId, step.StepOrder, Model.Pupil.UserName, tutorName)
If you think about it, what routes do is translate the url of a request into an action, so the parameters of my route are either the controller name, the action name or else they are the names of parameters in the action signature.
You can see now why naming two distinct route parameters with the same
name is such a bad idea (largely because it won't work).
So, look at your action signatures, and design your routes and your action links so that the everything marries up together.
MVC doesn't work by magic!! (Although the way it uses name conventions might lead you to believe it)