Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Username as parameter with blacklist validation

I am using the User model with the username as paramenter instead of the id. So currently I have this in my route:

resources :u, param: :username, :as => :user, :controller => :user

But now I would like to access the user profile via /:username, but I see a problem with it. I have routes like /login, /logout, /settings. A user can change his username. Now how can I handle, so that the user cannot have usernames like this routes above?

like image 466
Sylnois Avatar asked Jun 05 '26 19:06

Sylnois


2 Answers

Addressing your concern in isolation, you can ensure that conflicting usernames are prohibited using a blacklist.

class User < ApplicationRecord
  validates :username, exclusion: { in: %w{ login logout settings }
end

In practice, you will also want to blacklist usernames that can be misleading or convey undue authority. For example, you wouldn't want a user with the username “admin”, “administrator”, or “site_owner” because it could confuse other users.

You can also take advantage of the way Rails prioritizes routes (top down) to ensure that named routes are always given precedence over the user route:

Rails.application.routes.draw do
  get :login, to: 'sessions#new'
  get '/:username', to: 'users#show'
end 

GET /login #=> sessions#new
GET /foo #=> users#show

This enables you to add additional named routes over time that will take over username routes, which is a nice secondary protection.

For more on implementing vanity urls and using usernames in routes (instead of ids), I suggest taking a look at Changing user params to include their username.


Example to read in a file of blacklisted usernames for validation:

# app/models/concerns/blacklist.rb
module Blacklist
  def blacklist
    @_blacklist ||= File.readlines(Rails.root.join 'lib', 'blacklist.txt')
  end
end

# app/models/user.rb
class User < ApplicationRecord
  extend Blacklist
  validates :username, exclusion: { in: blacklist }
end
like image 54
coreyward Avatar answered Jun 07 '26 08:06

coreyward


You have two options here. The first is as suggested in the comments to your question: to have a list of excluded usernames and validate the user's username against that list before allowing them to create their account. Here's an example of one such list you could use.

The second is simpler: make the users route live at something like /u/username, instead of just /username.

like image 37
Ryan Bigg Avatar answered Jun 07 '26 09:06

Ryan Bigg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!