EzDev.org

devise

devise - Flexible authentication solution for Rails with Warden. Devise « Plataformatec Blog


Undefined local variable or method `unconfirmed_email' when registering users?

I just installed Devise in my app, configured the views and everything. However, when I click the sign up button I get this error:

NameError in Devise::RegistrationsController#create
undefined local variable or method `unconfirmed_email' for #<User:0x00000103721b28>

Why is this? Also, I'm using tlsmail to send emails out through my gmail business account. This might be a problem as well.


Source: (StackOverflow)

where is devise implementation of "authenticate_user!" method?

Where is devise implementation of authenticate_user! method?

I have been looking for it and have not found it so far.


Source: (StackOverflow)

Customizing Devise views in Rails

I'm using devise for user auth, but I have nice mockups for the signup, login, etc. pages. I've already done the rails generate devise:views User command and have all of the views in the views folder, however, when I replaced the registration/new.html.erb with my own new.html.erb, nothing changes nor looks different. It's as if I had done anything.

Anyone know what I'm doing wrong or at least how to successfully customize devise views

P.S. Is it important to note that I changed the route of devise/registration#new to /signup?


Source: (StackOverflow)

"WARNING: Can't mass-assign protected attributes"

I have used RESTful techniques to generate a model (in fact, I am using Devise gem, which does that for me), and I have added new fields called first_name and last_name to the model. Migration went fine. I added attr_accessor :first_name, :last_name to the model and expected it would just work. But when I try to mass-assign new instances with Doctor.create({:first_name=>"MyName"}) etc., I am getting errors saying I can't mass-assign protected attributes.

I thought the whole point of using attr_accessor was to get around the protectedness of the fields of a model. Can you help me make sense of this message?

Edit: oh, and by the way the records do not get created either. I thought they should be since this is just a warning, but they are not on the database.

Edit2: here is my model

class Doctor < User
  has_many :patients
  has_many :prescriptions, :through=> :patients

  validates_presence_of :invitations, :on => :create, :message => "can't be blank"

  attr_accessor :invitations
end

and the schema, which doesn't have the first_name and last_name because they are created in the users table, which is the ancestor of doctors. I used single table inheritance.

create_table :doctors do |t|
  t.integer :invitations

  t.timestamps
end

and this is the migration to change the users table

add_column :users, :first_name, :string
add_column :users, :last_name, :string
add_column :users, :type, :string

EDIT: here is the seed file. I am not including the truncate_db_table method, but it works.

%w{doctors patients}.each do |m|
  truncate_db_table(m)  
end  

Doctor.create(:invitations=>5, :email=>"email@gmail.com", :first_name=>"Name", :last_name=>"LastName")
Patient.create(:doctor_id=>1, :gender=>"male", :date_of_birth=>"1991-02-24")

Source: (StackOverflow)

devise and multiple "user" models

I'm using rails 3.2 and devise 2.0 and I'm quite new to Rails.

Requirements

I'd like to achieve the following:

  • have 2 or more "user" models, eg. Member, Customer, Admin
  • all models share some required fields (eg. email and password)
  • each model may have some unique fields (eg. company for Customer only)
  • some fields may be shared but not have the same validation (eg. name is required for Customer but optional for Member)
  • all fields must be filled during the registration process, so the forms are different
  • the login form should be unique

Possible solutions

I googled and searched StackOverflow for quite a long time, but nothing seems right to me (I'm a Java guy, sorry :) and now I'm quite confused. Two solutions came up:

Single devise user

That's the most frequent answer. Just create the default devise User and create relations between Member-->User and Customer-->User. My concern here is how can I achieve a customized registration process for each model? I tried different things but all ended as a mess!

Multiple devise users

This solves the custom registration process, and seems right to me, but the unique login form is a blocker. I found an answer on SO (Devise - login from two model) which suggests to override Devise::Models::Authenticatable.find_for_authentication(conditions). That seems complicated (?) and since I'm new to rails, I'd like to know if that could work?

Thanks for your advice!


Source: (StackOverflow)

Rails 3 using Devise: How to allow someone to log in using their Facebook account?

I have a Rails 3 application using Devise for authentication. Now I need to allow someone to log in using their Facebook account. I think this is called Facebook Connect, but I've also heard the term Facebook Graph API, so I'm not sure which one I'm asking for.

What do I need to do in order to integrate Facebook Connect with Devise?

Solution:

This question is pretty old now. A year ago, Devise v1.2 introduced OmniAuth support. Now Devise is at v2.1 (as of this writing) and using OmniAuth is even easier. Here is a great tutorial from the Devise wiki on using the omniauth-facebook gem with Devise to allow sign-in using Facebook.

Also check out this great tutorial on registering your application and working with the Facebook Graph API.


Source: (StackOverflow)

undefined method `devise_for' in rails

After I install devise and create a user model. I rake db:migrate and then I rake routes. I then get a error with "undefined method `devise_for' for #". What could be causing this error?


Source: (StackOverflow)

Is this Rails JSON authentication API (using Devise) secure?

My Rails app uses Devise for authentication. It has a sister iOS app, and users can log in to the iOS app using the same credentials that they use for the web app. So I need some kind of API for authentication.

Lots of similar questions on here point to this tutorial, but it seems to be out-of-date, as the token_authenticatable module has since been removed from Devise and some of the lines throw errors. (I'm using Devise 3.2.2.) I've attempted to roll my own based on that tutorial (and this one), but I'm not 100% confident in it - I feel like there may be something I've misunderstood or missed.

Firstly, following the advice of this gist, I added an authentication_token text attribute to my users table, and the following to user.rb:

before_save :ensure_authentication_token

def ensure_authentication_token
  if authentication_token.blank?
    self.authentication_token = generate_authentication_token
  end
end

private

  def generate_authentication_token
    loop do
      token = Devise.friendly_token
      break token unless User.find_by(authentication_token: token)
    end
  end

Then I have the following controllers:

api_controller.rb

class ApiController < ApplicationController
  respond_to :json
  skip_before_filter :authenticate_user!

  protected

  def user_params
    params[:user].permit(:email, :password, :password_confirmation)
  end
end

(Note that my application_controller has the line before_filter :authenticate_user!.)

api/sessions_controller.rb

class Api::SessionsController < Devise::RegistrationsController
  prepend_before_filter :require_no_authentication, :only => [:create ]

  before_filter :ensure_params_exist

  respond_to :json

  skip_before_filter :verify_authenticity_token

  def create
    build_resource
    resource = User.find_for_database_authentication(
      email: params[:user][:email]
    )
    return invalid_login_attempt unless resource

    if resource.valid_password?(params[:user][:password])
      sign_in("user", resource)
      render json: {
        success: true,
        auth_token: resource.authentication_token,
        email: resource.email
      }
      return
    end
    invalid_login_attempt
  end

  def destroy
    sign_out(resource_name)
  end

  protected

    def ensure_params_exist
      return unless params[:user].blank?
      render json: {
        success: false,
        message: "missing user parameter"
      }, status: 422
    end

    def invalid_login_attempt
      warden.custom_failure!
      render json: {
        success: false,
        message: "Error with your login or password"
      }, status: 401
    end
end

api/registrations_controller.rb

class Api::RegistrationsController < ApiController
  skip_before_filter :verify_authenticity_token

  def create
    user = User.new(user_params)
    if user.save
      render(
        json: Jbuilder.encode do |j|
          j.success true
          j.email user.email
          j.auth_token user.authentication_token
        end,
        status: 201
      )
      return
    else
      warden.custom_failure!
      render json: user.errors, status: 422
    end
  end
end

And in config/routes.rb:

  namespace :api, defaults: { format: "json" } do
    devise_for :users
  end

I'm out of my depth a bit and I'm sure there's something here that my future self will look back on and cringe (there usually is). Some iffy parts:

Firstly, you'll notice that Api::SessionsController inherits from Devise::RegistrationsController whereas Api::RegistrationsController inherits from ApiController (I also have some other controllers such as Api::EventsController < ApiController which deal with more standard REST stuff for my other models and don't have much contact with Devise.) This is a pretty ugly arrangement, but I couldn't figure out another way of getting access the methods I need in Api::RegistrationsController. The tutorial I linked to above has the line include Devise::Controllers::InternalHelpers, but this module seems to have been removed in more recent versions of Devise.

Secondly, I've disabled CSRF protection with the line skip_before_filter :verify_authentication_token. I have my doubts about whether this is a good idea - I see a lot of conflicting or hard to understand advice about whether JSON APIs are vulnerable to CSRF attacks - but adding that line was the only way I could get the damn thing to work.

Thirdly, I want to make sure I understand how authentication works once a user has signed in. Say I have an API call GET /api/friends which returns a list of the current user's friends. As I understand it, the iOS app would have to get the user's authentication_token from the database (which is a fixed value for each user that never changes??), then submit it as a param along with every request, e.g. GET /api/friends?authentication_token=abcdefgh1234, then my Api::FriendsController could do something like User.find_by(authentication_token: params[:authentication_token]) to get the current_user. Is it really this simple, or am I missing something?

So for anyone who's managed to read all the way to the end of this mammoth question, thanks for your time! To summarise:

  1. Is this login system secure? Or is there something I've overlooked or misunderstood, e.g. when it comes to CSRF attacks?
  2. Is my understanding of how to authenticate requests once users are signed in correct? (See "thirdly..." above.)
  3. Is there any way this code can be cleaned up or made nicer? Particularly the ugly design of having one controller inherit from Devise::RegistrationsController and the others from ApiController.

Thanks!


Source: (StackOverflow)

Devise update user without password

I want to update users attributes without password in devise. The case is like, if password and password confirmation fields are not blank then I need devise error and if they are blank then other user attributes need to be updated. How could I do this with devise?

Thanks in advance!


Source: (StackOverflow)

disabling Devise registration for production environment only

I am launching a beta site with a select group of users. I want to disable registration in the production environment only, and only for a short period of time (i.e. I don't want to nuke my registration altogether). I know I can simply hide the "sign up" link, but I suspect that hackers smarter than I can still use the RESTful routes to accomplish registrations. What's the best way to disable registration so my test/development environments still work, but production is affected? Thanks for any pointers.

I've tried pointing named scopes in such a way that "sign_up" goes to "sign_in", but it didn't work. Here's what I've tried:

devise_scope :user do
    get "users/sign_in", :to => "devise/sessions#new", :as => :sign_in
    get "users/sign_up", :to => "devise/sessions#new", :as => :sign_up
end

Ideally, we'd send the user to a "pages#registration_disabled" page or something like that. I just wanted to get something working I can play around with.

EDIT: I've changed the model as requested, then added the following to /spec/user_spec.rb

describe "validations" do
    it "should fail registration if in production mode" do
      ENV['RAILS_ENV'] = "production"
      @user = Factory(:user).should_not be_valid
    end
end

it is passing as "true" rather than false. Is there a way to mock up the production environment? I'm just spit-balling this one.

Thanks!


Source: (StackOverflow)

Share session (cookies) between subdomains in Rails?

I have an app setup where each user belongs to a company, and that company has a subdomain (I am using basecamp style subdomains). The problem that I am facing is that rails is creating multiple cookies (one for lvh.me and another for subdomain.lvh.me) which is causing quite a few breaks in my application(such as flash messages being persistent though out all requests once signed in).

I have this in my /cofig/initilizers/session_store.rb file:

AppName::Application.config.session_store :cookie_store, key: '_application_devise_session', domain: :all

The domain: :all seems to be the standard answer I found on Google, but that doesn't seem to be working for me. Any help is appreciated!


Source: (StackOverflow)

rails - "WARNING: Can't verify CSRF token authenticity" for json devise requests

How can I retrieve the CSRF token to pass with a JSON request?

I know that for security reasons Rails is checking the CSRF token on all the request types (including JSON/XML).

I could put in my controller skip_before_filter :verify_authenticity_token, but I would lose the CRSF protection (not advisable :-) ).

This similar (still not accepted) answer suggests to

Retrieve the token with <%= form_authenticity_token %>

The question is how? Do I need to do a first call to any of my pages to retrieve the token and then do my real authentication with Devise? Or it is an information one-off that I can get from my server and then use consistently (until I manually change it on the server itself)?


Source: (StackOverflow)

different layout for sign_in action in devise

I'm trying to use a different/custom layout named "devise" for the sign_in action. I found this page in the devise wiki, and the second example even says you can do it per-action (in this case, sign_in action), but it shows no example of doing that. Someone on IRC told me I could try this:

class ApplicationController < ActionController::Base
  protect_from_forgery

  layout :layout_by_resource

  def layout_by_resource
    if devise_controller? && resource_name == :user && action_name == 'sign_in'
      "devise"
    else
      "application"
    end
  end
end

But it does not seem to be working as it's still loading the default application layout. I would appreciate any help.


Source: (StackOverflow)

Weird issue with devise valid_password?

For the past 2 hours, I have been trying to debug a weird issue in devise which is not letting me login.

Here's the stuff I'm referring too:

password 
=> 'vinodsobale'

password == 'vinodsobale'
=> true

resource.valid_password?(password)

=> false

resource.valid_password?('vinodsobale')

=> true

Attaching the screenshot as well:

enter image description here Note: I have enabled debugger inside devise so the above code is devise internal code.

To me, it looks like a issue in Devise.secure_compare.


Source: (StackOverflow)

Devise - How do I forbid certain users from signing in?

I am using Devise for authentication in my application.

How do I forbid certain users from signing in - kind of disable a user?


Source: (StackOverflow)