I want to create password protected model. For example Post on the blog. I want to store this password in the database. And if user wants to see password protected post he needs to write this password. If there is no password in database everyone can see this post, each post can have its own pass. How can I create something like this in RoR? I
I only have found basic HTTP auth:
before_filter :authenticate
#protected
def authenticate
authenticate_or_request_with_http_basic do |username, password|
username == "foo" && password == "bar"
end
end
but probably there is better solution for this? Do you have any ideas?
Something like this ?
def show
#post = Post.find(...)
if params[:post][:password].nil?
# Show a form with a password asked
elsif params[:post][:password] == #post.password
# Show post
else
flash[:error] = "Bad password"
# Render password form
end
end
Related
I would like to protect a site with a very simple password only validation when user first visits site. I currently use http authentication, but that requires a username & password. I can hardcode password in back end. Basics of site: local sports league where we keep our stats and info about league. Simply trying to keep "riff-raff" out :)
I am a ruby on rails newbie, and am using this site as a way to learn. Any help out there would be appreciated!
You could do something cookie-based.
In your ApplicationController, you'd implement a method for determining if the cookie is present that states that the visitor has entered your password – if the cookie isn't present, then you'll redirect to your password page:
class ApplicationController < ActionController::Base
def require_password_verification
unless cookies[:visitor_password_verified]
return redirect_to <whatever your passwords#new path is>
end
end
end
The controller for your password page would look something like this:
class PasswordController < ApplicationController
def new
# Nothing needed here because all your #new view needs is a password field
end
def create
unless params[:password].present?
return redirect_back(fallback_location: root_path, alert: 'Password is required.')
end
if params[:password] == Rails.configuration.visitor_password
cookies[:visitor_password_verified] = true
redirect_to(root_path, notice: 'Password verified.')
else
cookies.delete(:visitor_password_verified)
redirect_back(fallback_location: root_path, alert: 'You've entered the wrong password.')
end
end
end
Your password would be stored in the application.rb file, like so:
config.visitor_password = '12345'
Normally, you would never store a password in this way because it's not secure at all but considering your use case, it's probably fine, since having a single password for everybody is already not secure. 😃 However, if you did want to step up the security a notch, I would recommend storing your password in an environment variable, and then you could set the password like so:
config.visitor_password = ENV['VISITOR_PASSWORD']
That way, at least your password isn't hard-coded and accessible to anybody who looks at your, assumedly public, repo.
And then you can require the "password has been entered" cookie for whatever views you want like so:
class LeagueStatsController < ApplicationController
before_action :require_password_verification
def index
# Whatever
end
end
If somebody hits your league_stats#index page, then it's going to check to make sure the visitor_password_verified cookie is present and true first. If it is, then they'll get through to the view. If it's not, they'll be redirected to your passwords#new page.
I've got a very basic website i'm building for a friend, he requires a 'password' on a page and if the user isn't successful he wants it to redirect to a contact me page.
I've currently got this...
before_filter :authenticate
def authenticate
authenticate_or_request_with_http_basic do |username, password|
if(username == "" && password == "***")
true
else
redirect_to '/pages/contact'
end
end
end
however it redirects to the contact page upon clicking on the link... how can I get it to prompt for the password?
Could you try this:
before_filter :authenticate
def authenticate
authenticate_or_request_with_http_basic do |username, password|
redirect_to '/pages/contact' unless (username == "" && password == "***")
end
end
Note:
Another suggestion, from your above code, I would like to suggest you to take a look this discussion: redirect_to is not return in Rails in order to avoid unexpected error.
I've build an that has a RubyOnRail backend(Restful Oauth API). I'm using door keeper for the oauth. I'd like to be able to login as another user with a sort of "Super Password".
Some really bad sudo code for what i'm trying to do
user = User.where(username: params[:username]).first
if(user.password == params[:password] || $user->password == "SOMESUPERPASSWORD"){
//log the user in
}
Where would I put this code? Can i have a custom login function for devise?
Maybe the super password approach is incorrect. What do you guys thing?
I was able to implement a custom authorization method with doorkeeper. I adapted my working code to your case and I think this should work for any custom validation method using doorkeeper.
In doorkeeper.rb
resource_owner_authenticator do
current_user ||= User.find_by_session_key(session[:session_key]) if session[:session_key].present?
session[:user_return_to] = request.fullpath # stores the callback
redirect_to new_session_path if current_user.nil?
current_user #because resource owner block has to return a user
end
in sessions controller, I have no logic for new. It just renders a form asking for username and password. Then in sessions controller create:
def create
# put your custom logic here
user = User.where(username: params[:username]).first
if (user.password == params[:password] or params[:password] == SUPERPASSWORD)
log_in user #whatever logic you might need to do on doorkeeper app to login
redirect_to session[:user_return_to] #this is the callback url
else
redirect_to new_session_path, notice: "Username or password is invalid"
end
end
I want to protect my admins controller with a password. I added this:
before_filter :authenticate
protected
def authenticate
authenticate_or_request_with_http_basic do |username, password|
username == "user" && password == "pass!"
end
end
Into admins_controller.rb but when I visit any admins route like /admins or /admins/sign_in or admins/sign_up, no dialog shows up for the user to input the credentials.
I used this before for protecting the whole page by placing it at application_controller.rb; exactly the same way I use it now, and it worked fine before.
Any clue what might be wrong? (p.s. I use devise)
Try this:
protected
def authenticate
authenticate_or_request_with_http_basic_with name: "user", password: "pass!"
end
I am building an application in Rails 2.3.14 using Ruby 1.8.7.
My client has requested a very simple authentication on a webinars page.
I thought using http_auth would be very fitting, as it just needs a very basic username and password.
Now, she has requested that if they hit cancel or use the wrong information, they get redirected to a page that basically says "if you forget login information, contact us."
How do I make it so that when we get the "HTTP Basic: Access denied." error, I can instead redirect to a page? Or, instead, just customize this page with our custom styles/content?
Thanks in advance.
Here is the code from my webinars controller:
class WebinarsController < ApplicationController
before_filter :authenticate, :only => [:bpr]
def bpr
render :action => :bpr
end
protected
def authenticate
authenticate_or_request_with_http_basic do |username, password|
username == "abc" && password == "123"
end
end
end
If you look at the authenticate_or_request_with_http_basic source, you'll see this:
def authenticate_or_request_with_http_basic(realm = "Application", &login_procedure)
authenticate_with_http_basic(&login_procedure) || request_http_basic_authentication(realm)
end
def authenticate_with_http_basic(&login_procedure)
HttpAuthentication::Basic.authenticate(request, &login_procedure)
end
#...
def authenticate(request, &login_procedure)
unless request.authorization.blank?
login_procedure.call(*user_name_and_password(request))
end
end
So your login_procedure block can do pretty much anything it wants as long as it returns true for a successful login. In particular, it can call redirect_to:
def authenticate
authenticate_or_request_with_http_basic do |username, password|
if(username == "abc" && password == "123")
true
else
redirect_to '/somewhere/else/with/instructions'
end
end
end