Giter Site home page Giter Site logo

omniauth / omniauth-identity Goto Github PK

View Code? Open in Web Editor NEW
345.0 345.0 99.0 1.28 MB

A simple login and password strategy for OmniAuth.

License: MIT License

Ruby 100.00%
authentication authentication-middleware authentication-strategy omniauth omniauth-strategy

omniauth-identity's Introduction

OmniAuth: Standardized Multi-Provider Authentication

Gem Version Ruby TruffleRuby JRuby Code Climate Coverage Status

This is the documentation for the in-development branch of OmniAuth. You can find the documentation for the latest stable release here

An Introduction

OmniAuth is a library that standardizes multi-provider authentication for web applications. It was created to be powerful, flexible, and do as little as possible. Any developer can create strategies for OmniAuth that can authenticate users via disparate systems. OmniAuth strategies have been created for everything from Facebook to LDAP.

In order to use OmniAuth in your applications, you will need to leverage one or more strategies. These strategies are generally released individually as RubyGems, and you can see a community maintained list on the wiki for this project.

One strategy, called Developer, is included with OmniAuth and provides a completely insecure, non-production-usable strategy that directly prompts a user for authentication information and then passes it straight through. You can use it as a placeholder when you start development and easily swap in other strategies later.

Getting Started

Each OmniAuth strategy is a Rack Middleware. That means that you can use it the same way that you use any other Rack middleware. For example, to use the built-in Developer strategy in a Sinatra application you might do this:

require 'sinatra'
require 'omniauth'

class MyApplication < Sinatra::Base
  use Rack::Session::Cookie
  use OmniAuth::Strategies::Developer
end

Because OmniAuth is built for multi-provider authentication, you may want to leave room to run multiple strategies. For this, the built-in OmniAuth::Builder class gives you an easy way to specify multiple strategies. Note that there is no difference between the following code and using each strategy individually as middleware. This is an example that you might put into a Rails initializer at config/initializers/omniauth.rb:

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :developer unless Rails.env.production?
  provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
end

You should look to the documentation for each provider you use for specific initialization requirements.

Integrating OmniAuth Into Your Application

OmniAuth is an extremely low-touch library. It is designed to be a black box that you can send your application's users into when you need authentication and then get information back. OmniAuth was intentionally built not to automatically associate with a User model or make assumptions about how many authentication methods you might want to use or what you might want to do with the data once a user has authenticated. This makes OmniAuth incredibly flexible. To use OmniAuth, you need only to redirect users to /auth/:provider, where :provider is the name of the strategy (for example, developer or twitter). From there, OmniAuth will take over and take the user through the necessary steps to authenticate them with the chosen strategy.

Once the user has authenticated, what do you do next? OmniAuth simply sets a special hash called the Authentication Hash on the Rack environment of a request to /auth/:provider/callback. This hash contains as much information about the user as OmniAuth was able to glean from the utilized strategy. You should set up an endpoint in your application that matches to the callback URL and then performs whatever steps are necessary for your application.

The omniauth.auth key in the environment hash provides an Authentication Hash which will contain information about the just authenticated user including a unique id, the strategy they just used for authentication, and personal details such as name and email address as available. For an in-depth description of what the authentication hash might contain, see the Auth Hash Schema wiki page.

Note that OmniAuth does not perform any actions beyond setting some environment information on the callback request. It is entirely up to you how you want to implement the particulars of your application's authentication flow.

rack_csrf

omniauth is not OOTB-compatible with rack_csrf. In order to do so, the following code needs to be added to the application bootstrapping code:

OmniAuth::AuthenticityTokenProtection.default_options(key: "csrf.token", authenticity_param: "_csrf")

Rails (without Devise)

To get started, add the following gems

Gemfile:

gem 'omniauth'
gem "omniauth-rails_csrf_protection"

Then insert OmniAuth as a middleware

config/initializers/omniauth.rb:

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :developer if Rails.env.development?
end

Additional providers can be added here in the future. Next we wire it all up using routes, a controller and a login view.

config/routes.rb:

  get 'auth/:provider/callback', to: 'sessions#create'
  get '/login', to: 'sessions#new'

app/controllers/sessions_controller.rb:

class SessionsController < ApplicationController
  def new
    render :new
  end

  def create
    user_info = request.env['omniauth.auth']
    raise user_info # Your own session management should be placed here.
  end
end

app/views/sessions/new.html.erb:

<%= form_tag('/auth/developer', method: 'post', data: {turbo: false}) do %>
  <button type='submit'>Login with Developer</button>
<% end %>

Now if you visit /login and click the Login button, you should see the OmniAuth developer login screen. After submitting it, you are returned to your application at Sessions#create. The raise should now display all the Omniauth details you have available to integrate it into your own user management.

If you want out of the box usermanagement, you should consider using Omniauth through Devise. Please visit the Devise Github page for more information.

Rails API

The following middleware are (by default) included for session management in Rails applications. When using OmniAuth with a Rails API, you'll need to add one of these required middleware back in:

  • ActionDispatch::Session::CacheStore
  • ActionDispatch::Session::CookieStore
  • ActionDispatch::Session::MemCacheStore

The trick to adding these back in is that, by default, they are passed session_options when added (including the session key), so you can't just add a session_store.rb initializer, add use ActionDispatch::Session::CookieStore and have sessions functioning as normal.

To be clear: sessions may work, but your session options will be ignored (i.e. the session key will default to _session_id). Instead of the initializer, you'll have to set the relevant options somewhere before your middleware is built (like application.rb) and pass them to your preferred middleware, like this:

application.rb:

config.session_store :cookie_store, key: '_interslice_session'
config.middleware.use ActionDispatch::Cookies # Required for all session management
config.middleware.use ActionDispatch::Session::CookieStore, config.session_options

(Thanks @mltsy)

Logging

OmniAuth supports a configurable logger. By default, OmniAuth will log to STDOUT but you can configure this using OmniAuth.config.logger:

# Rails application example
OmniAuth.config.logger = Rails.logger

Origin Param

The origin url parameter is typically used to inform where a user came from and where, should you choose to use it, they'd want to return to. Omniauth supports the following settings which can be configured on a provider level:

Default:

provider :twitter, ENV['KEY'], ENV['SECRET']
POST /auth/twitter/?origin=[URL]
# If the `origin` parameter is blank, `omniauth.origin` is set to HTTP_REFERER

Using a differently named origin parameter:

provider :twitter, ENV['KEY'], ENV['SECRET'], origin_param: 'return_to'
POST /auth/twitter/?return_to=[URL]
# If the `return_to` parameter is blank, `omniauth.origin` is set to HTTP_REFERER

Disabled:

provider :twitter, ENV['KEY'], ENV['SECRET'], origin_param: false
POST /auth/twitter
# This means the origin should be handled by your own application. 
# Note that `omniauth.origin` will always be blank.

Resources

The OmniAuth Wiki has actively maintained in-depth documentation for OmniAuth. It should be your first stop if you are wondering about a more in-depth look at OmniAuth, how it works, and how to use it.

OmniAuth for Enterprise

Available as part of the Tidelift Subscription.

The maintainers of OmniAuth and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. Learn more.

Supported Ruby Versions

OmniAuth is tested under 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, truffleruby, and JRuby.

Versioning

This library aims to adhere to Semantic Versioning 2.0.0. Violations of this scheme should be reported as bugs. Specifically, if a minor or patch version is released that breaks backward compatibility, that version should be immediately yanked and/or a new version should be immediately released that restores compatibility. Breaking changes to the public API will only be introduced with new major versions. As a result of this policy, you can (and should) specify a dependency on this gem using the Pessimistic Version Constraint with two digits of precision. For example:

spec.add_dependency 'omniauth', '~> 1.0'

License

Copyright (c) 2010-2017 Michael Bleigh and Intridea, Inc. See LICENSE for details.

omniauth-identity's People

Contributors

amatsuda avatar andrewfreemantle avatar andyroberts avatar bgentry avatar calebwoods avatar coreyhaines avatar froderik avatar george-hudson avatar ghiblin avatar jbueler avatar kevinwmerritt avatar mamantoha avatar mbleigh avatar mhat avatar natebird avatar pboling avatar tyabe avatar webdestroya avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

omniauth-identity's Issues

โ€œRouting Error No route matches {}โ€ when omniauth failed on registration

I am not sure if this is a right place to put this question... Sorry for this...
But I am in dispair...
Can somebody help me?

(Originally I asked this question at http://stackoverflow.com/questions/11506734/routing-error-no-route-matches-when-omniauth-failed-on-registration)

I am using omniauth-identity and configure its "fail on registration".

My files:

config/initializers/omniauth.rb

OmniAuth.config.logger = Rails.logger

Rails.application.config.middleware.use OmniAuth::Builder do
  #...
  provider :identity, on_failed_registration: lambda { |env|
    IdentitiesController.action(:new).call(env)
  }
end

config/routes.rb

Wie::Application.routes.draw do
  root to: 'categories#index'

  ActiveAdmin.routes(self)
  devise_for :admin_users, ActiveAdmin::Devise.config

  match 'auth/:provider/callback', to: 'sessions#create'
  match 'auth/failure', to: 'sessions#failure'
  match 'signout', to: 'sessions#destroy', as: 'signout'
  resources :identities#, only: [:new]
  resources :categories, path: '', only: [:index] do
    resources :entries, path: '', only: [:index, :show]
  end
end

app/controllers/identities_controller.rb

class IdentitiesController < ApplicationController
  def new
    ariane.add "New Account"

    @identity = env['omniauth.identity']
  end
end

When I have a failure on registration (passing incorrect mail), I get the following:

in browser:

Routing Error

No route matches {} Try running rake routes for more information on
available routes.

in server log:

Started POST "/auth/identity/register" for 127.0.0.1 at 2012-07-16
17:35:48 +0300 (0.1ms) begin transaction Identity Exists (0.2ms)
SELECT 1 AS one FROM "identities" WHERE "identities"."email" = 'foo'
LIMIT 1 (0.1ms) rollback transaction Processing by
IdentitiesController#new as HTML Parameters: {"utf8"=>"โœ“",
"authenticity_token"=>"HIDDEN :)>=",
"name"=>"", "email"=>"foo", "password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]", "commit"=>"Register"}
Rendered identities/new.html.erb within layouts/application (11.2ms)
Completed 500 Internal Server Error in 44ms

ActionController::RoutingError (No route matches {}):
app/views/layouts/application.html.erb:35:in
_app_views_layouts_application_html_erb___1224394470845933684_70120630781720' config/initializers/omniauth.rb:8:incall'
config/initializers/omniauth.rb:8:in `block (2 levels) in <top
(required)>'

Rendered
/Users/ayia/.rvm/gems/ruby-1.9.3-p125@global/gems/actionpack-3.2.6/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (0.6ms)

What can be the reason for this? What did I wrong?

UPDATE
What I do not understand is - why I get Started POST "/auth/identity/register"? According to omniauth configuration I should get the view correspondent to the IdentitiesController.action(:new), i.e. /identities/new ...

need help

how can user and customer registration using identity? those 2 has difference registration and session . user to backend application. customer to front end

Show validation errors on registration form

I noticed by default, if there's a validation error in the registration form, it brings the user back to the form without displaying any error messages as to what went wrong. There is an on_failed_registration option for just this scenario, but it requires you implement a rack endpoint (or Rails controller action) to handle the error and display a form. This takes away from the quick and easy appeal of this gem. It would be much better if the registration form had some validation handling by default.

Since different ORMs can handle validation errors differently, I suggest adding a simple "error_messages" method on the Identity model which simply returns an array of validation errors. Behind the scenes this can do whatever is necessary for that ORM, such as calling "errors.full_messages" in Active Record.

Disable built-in forms

When using custom login/registration forms (as shown in Railscast 304), the default forms e.g. on "/auth/identity/register" are still being served. It would be nice to add an option with a path to which these routes are redirected.

A hack is described on Stackoverflow, however, it involves monkey patching and might not be the most future proof solution:

http://stackoverflow.com/questions/8854703/override-auth-identity-page-of-omniauth-identity

Another workaround described elsewhere does something like this:

Rails.configuration.middleware.insert_before(Rack::Lock, Rack::Rewrite) do
  rewrite '/auth/identity/register', '/sign_in', method: /get/i
end

This won't work with threadsafe!, though: ".../actionpack-3.2.13/lib/action_dispatch/middleware/stack.rb:120:in 'assert_index': No such middleware to insert before: Rack::Lock (RuntimeError)"

how to put length validation on omniauth-identity password field in rails 4

Hi, I am trying to put form validations on omniauth-identity in rails 4. However, it is failing continuously with the following error:

["Password can't be blank",
"Password can't be blank",
"Password is too short (minimum is 8 characters)"]

My validations look like this in identity.rb

validates :name, presence: true, format: { with: Constants::NAME_REGEX }
validates :email, presence: true, format: { with: Constants::EMAIL_REGEX }
validates :password, presence: true, length: { minimum: 8 }

Can you point out the mistake or what I may be doing wrong?

Not verifying the email address??

Hi,

If I understand correctly, omniauth-identity is allowing the user to associate an email+password for login. But there is no check to make sure the email actually belongs to that user. They are granted the permission immeadiately.

Now, my worry is with the trend of multi omniauth strategies , say I have well known user [email protected] that logged in via Facebook, but not Identity. Then I come along and I login using his email address and make up a password, won't I get access to his account?

That is based on some of the blogs I read that associate multiple omni auth strategies to the same account via email address.

Let me know,

Peter

Not preventing duplicate emails

I'm using Mongoid and OmniAuth Identity, only requiring email address. The sign-up form is allowing me to create multiple identities with the same email address. I would have expected some sort of error there, saying that email address is already taken. Am I missing something?

Gem hosted at Rubygems is different from the one on Github

The omniauth-identity gem on Rubygems has the same version as the one on Github (1.1.0), but the code is different. A quick reference point: the docs on Github reference a locate_conditions option, whereas the docs on Rubygems do not: http://rubydoc.info/gems/omniauth-identity/1.1.0/frames

For anyone who needs the locate_conditions feature, you can get it by install the gem with this line in your Gemfile:

gem 'omniauth-identity', git: 'https://github.com/intridea/omniauth-identity.git'

uninitialized constant OmniAuth::Identity::Models::DataMapper (NameError)

I'm receiving a NameError in a sinatra app with datamapper:

Model:

class Identity
  include DataMapper::Resource
  include OmniAuth::Identity::Models::DataMapper

  property :name,            String
  property :email,           String
  property :password_digest, String
end

...

use OmniAuth::Builder do
  provider :twitter, 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXX'
  provider :identity, :fields => [:email]
end

Gemfile

gem 'omniauth-identity'

Appfile:

require 'omniauth-identity'

Error Message which I receive when I run my app:

`<class:Identity>': uninitialized constant OmniAuth::Identity::Models::DataMapper (NameError)

Twitter works fine before I included Identity.

To associate or not to associate

The README says:

OmniAuth Identity is different from many other user authentication systems in that it is not intended to be associated with your primary User model. Instead, the Identity model should be associated with your User model..

That sounds contradictory and should be reworded.

Issues with Identity and Datamapper Associations

I seem to be running into an issue using the Identity provider with Datamapper. I'm using Sinatra and have created the following two models.

class Identity
include DataMapper::Resource
include OmniAuth::Identity::Models::DataMapper

attr_accessor :password_confirmation

property :id, Serial
property :email, String
property :password_digest, Text

belongs_to :user
end

AND

class User
include DataMapper::Resource

property :id, Serial
property :username, String, :required => true, :index => true
property :name, String, :required => true
property :bio, Text
property :created_at, DateTime
property :updated_at, DateTime

has n, :identities
end

When using the above models as they are (with the associations in place), I am unable to successfully create a new Identity using '/auth/identity/register'. However, if I remove the associations, the new Identity is created without a problem. I'm pretty new to Ruby and am still learning my way around OmniAuth so perhaps I'm missing a simple configuration or something but I can't seem to get past this hurdle. Has anyone else had this problem?

Lack of CSRF token w/ Rails4

When redirect to /auth/:provider/callback, omniauth-identity does not have CSRF token. This brings 2 problems.

  • CSRF risk.
  • No persist session, like authentication data and session[:user_id], because no CSRF token causes no authentication token.

Below is related issue, and this is very rails-specific code, I also think.
Adding authenticity token so session will persist

With:
omniauth-identity v1.1.0, rails v4.1(perhaps above v4.0)

invalid_credentials error

When I try do login with incorrect username or password I get this error:
OmniAuth::Error
invalid_credentials

It don't render /auth/failure, just raise this error and stop. When I login with a correct username/password it's works fine.

Someone had this error too?

Custom validation is impossible

Right now, it's impossible to enable some sort of custom validations on user registration, such as captchas or the like. I propose (and am willing to write) an additional option like :on_registration_failed which would allow you to add a validation callback a la

Rails.application.config.middleware.use OmniAuth::Builder do 
  provider :identity,
    model: User,
    fields: [:email, :first_name, :last_name, :phone, :title],
    on_failed_registration: lambda { |env| HomeController.action(:index).call(env) },
    on_validation: lambda { |env| validate_captcha.call(env) }
end
  def validate_captcha env
    return true if recaptcha_valid?

    return false
  end๏ฟฝ

Thoughts?

Purpose of auth_key= in model adapters is unclear

All the model adapters feature an override of auth_key= that looks something like this:

        def self.auth_key=(key)
          super
          validates_uniqueness_of key, :case_sensitive => false
        end

Problem is, there's no superclass method, so this blows up if you try to actually call it. Is this supposed to be patching the auth_key method instead?

Invalid password behavior broken in latest rails (3.2.3)

I cloned railscast episode 304 and got it running. Then updated the Gemfile like so:

source 'http://rubygems.org'

gem 'rails', '3.2.3'
gem 'sqlite3'

group :assets do
gem 'sass-rails', '> 3.2.3'
gem 'coffee-rails', '
> 3.2.1'
gem 'uglifier', '>= 1.0.3'
end

gem 'jquery-rails'

gem 'bcrypt-ruby', '~> 3.0.0'

gem 'omniauth-twitter'
gem 'omniauth-facebook'
gem 'omniauth-google-oauth2'
gem 'omniauth-identity'

When entering an invalid password for a valid user I get the following error page:

OmniAuth::Error

invalid_credentials
Rails.root: /home/[redacted]/Workspace/episode-304/auth-after

Application Trace | Framework Trace | Full Trace
Request

Parameters:

{"utf8"=>"โœ“",
"authenticity_token"=>"[redacted]",
"auth_key"=>"[redacted]",
"password"=>"[FILTERED]",
"commit"=>"Login"}
Show session dump

Show env dump

Response

Headers:

None

Make omniauth-identity play nicely with multiple authentication

I've been implementing multiple authentication with different omniauth providers, and while I appreciate the drop-in-and-go simplicity of omniauth-identity, it creates an Identity object (line 63) as part of its registration process that subsequently isn't found by the multiple providers implementation guide because the creation doesn't populate the Identity.provider attribute - because it doesn't know about it!

Here's the relevant part of the code from the guide:

# app/models/identity.rb
class Identity < ActiveRecord::Base
  belongs_to :user

  def self.find_with_omniauth(auth)
    find_by(uid: auth['uid'], provider: auth['provider'])
  end

  ...

end

Possible fix: Add an option to tell omniauth-identity that there's a 'provider' attribute on the Identity object and to populate it.

Unless you know another way to make it play a little more seamlessly? Thanks :o)

Remove password validations

This line here forces a validation on the password_digest attribute, which outputs silly validation errors like

Password digest can't be blank

No normal user knows what a password digest is. As it's not possible to remove validations once they are added, I propose you simply remove the validations altogether. Leave it up to the developer to enforce their own validations.

Access identity object in case of login failure

I am struggling to access the identity object in case of failed login inside my SessionsController#failure action.

I was wondering if it is possible to be accessed as in IdentitiesController#new action ( env['omniauth.identity'] ).

Password hash doesn't use salt

Proposoal

This gem should use salted passwords in order to prevent a rainbow table based attack.

I think the easiest way to do this is to have a required field (called "Salt") in the Identity model, which would be filled with a random value when a new record in the table is initialized. This salt should then be combined with the password which is entered, prior to creating the hash.

Benefits

The advantages of including salt are:

  1. If two people have the same password, a person viewing the hashed password can't tell
  2. Prevents attacks which utilize pre-computed dictionaries of common passwords

Prevent unauthenticated user from registering new user

This is probably a shortcoming on my part, but I can't figure out how to prevent an unauthenticated user from accessing the /auth/identity/register route.

This is necessary in any application where access is not intended to be "open", and an administrator (or any other specific role) is required to create an account. Any application intended to serve a small community on an invitation-only basis needs this functionality.

create a new user from controller

I need to create a new user of OMNIAUTH IDENTITY from a controller which accepts email and password along with the controller specific data.

I tried but I could get it to work.

redirect_to("/auth/identity/register?email=" + URI::escape(params["email"]) + "&password="+ URI::escape(params["email"]))

Or something like
Identity.create(:email => params["email"], :password=>params["email"])
session[:authhash] = @authhash
@newuser = User.new # from session[:authhash]
Other Processing

License

There doesn't appear to be a license defined for this library. I'm assuming it's MIT, since the rest of the Omniauth libraries are ... but there is no reference in the gemspec nor a LICENSE file in the root.

Retire views?

I think that omniauth-identity is a great gem for adding email authentication to an app, but I haven't any use the built-in views and every app is different in style.

I would like to hear if we could retire these built-in views?

Integration test with capybara

With an integration test that looks like

it 'should make a new user' do
  lambda do
    visit register_path
    fill_in 'first_name',            :with => 'bob'
    fill_in 'last_name',             :with => 'hope'
    fill_in 'email',                 :with => '[email protected]'
    fill_in 'password',              :with => 'password'
    fill_in 'password_confirmation', :with => 'password'

     click_button 'Go!'
     #    save_and_open_page
     page.current_path.should eq(registration_step_one_path)
  end.should change(User, :count).by(1)
end

The POST path '/auth/identity/register' is not found by Capybara

Custom fields breaking registration?

Hey,

I'm having a big problem trying to add additional fields to the registration process where it somewhere losing the email address internally?

If I leave everything as standard, then the registration works perfectly. Now I want to add a date of birth, and gender field to the process, so in my omniauth confi, I've added

provider :identity, fields: [:name, :email, :gender, :dob_year, :dob_month, :dob_day]

And that's fine, if I load the default registration form provided by omniauth-identity they show up, but when I then try and register I have issues. It appears to create the Identity on the database itself which is great, but then when it attempts to retrieve the Identity (I assume to login) I see the following in the logs :

Started POST "/auth/identity/register" for 127.0.0.1 at 2012-08-08 13:47:12 +0100
   (13.3ms)  SELECT 1 FROM "identities" WHERE "identities"."email" = '[email protected]' LIMIT 1
Binary data inserted for `string` type on column `password_digest`
  SQL (39.7ms)  INSERT INTO "identities" ("created_at", "dob_day", "dob_month", "dob_year", "email", "gender", "name", "password_digest", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)  [["created_at", Wed, 08 Aug 2012 12:47:13 UTC +00:00], ["dob_day", 9], ["dob_month", 2], ["dob_year", 1989], ["email", "[email protected]"], ["gender", "Male"], ["name", "tester"], ["password_digest", "$2a$10$1apvNK5SKO.0TiOUByRfQ.Ul8NXRkLIErtiDjPtI7DtnFKK7GL8Pe"], ["updated_at", Wed, 08 Aug 2012 12:47:13 UTC +00:00]]
(identity) Callback phase initiated.
  Identity Load (0.3ms)  SELECT "identities".* FROM "identities" WHERE "identities"."email" IS NULL LIMIT 1
(identity) Authentication failure! invalid_credentials encountered.

It then redirects me back to my login screen. I can then login and it's fine, but I need the redirect after registration to work.
Any reason this is happening?

I have added the fields to my Identity model with

attr_accessible :name, :email, :password, :password_confirmation, :dob_year, :dob_month, :dob_day, :gender

I am really stumped and cannot figure out what's causing this. Please can someone help?

Password Reset

I have attempted to create a password reset process for users that make a mistake on signup, or forget their password. It seems though that simply updating the attributes of the identity model where the password is stored does not work.

Does anyone have a good solution for this?

Potential Problem with Rails 3.2 & ActiveRecord

Here is my Identity model:

class Identity < OmniAuth::Identity::Models::ActiveRecord
  validates :name, :presence => true
  validates :email, :presence => true, :email => true
end

When trying to use the class, I get this lovely error from Postgres:

ActiveRecord::StatementInvalid (PGError: ERROR:  relation "active_records" does not exist
LINE 4:              WHERE a.attrelid = '"active_records"'::regclass
                                        ^
:             SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
              FROM pg_attribute a LEFT JOIN pg_attrdef d
                ON a.attrelid = d.adrelid AND a.attnum = d.adnum
             WHERE a.attrelid = '"active_records"'::regclass
               AND a.attnum > 0 AND NOT a.attisdropped
             ORDER BY a.attnum
):

It seems through the combination of AR's abstract_class and inheritance something is going wrong. Adding a self.table_name = "identities" solves the problem though:

class Identity < OmniAuth::Identity::Models::ActiveRecord
  self.table_name = 'identities'

  validates :name, :presence => true
  validates :email, :presence => true, :email => true
end

Provider and UID attributes aren't getting set

Hi,

I tried to follow this tutorial:
https://github.com/intridea/omniauth/wiki/Managing-Multiple-Providers

but came into an issue where the Identity records were getting created with the provider and uid attributes not set.

I'm trying omniauth-identity out on rails 4.0.0.beta1. So my best guess is that strong_parameters aren't allowing these attributes to be mass-assigned? I'm not sure how strong_parameters work with Rack middleware or if I'm just totally off the mark.

The work around for me was to replace:

def self.create_with_omniauth(auth)
  create(uid: auth['uid'], provider: auth['provider'])
end

with something along the lines of

def self.find_and_update_with_omniauth(auth, password)
  identity = find(auth['uid'])
  identity.update_attributes(uid: auth['uid'],
                             provider: auth['provider'],
                             email: auth['info']['email'],
                             password: password)
  identity.save
  identity
end

It's definitely not elegant and I'm not sure if it's solving the root cause of the issue, but just wanted to give you a heads up.

Just out of curiousity, it seems like identity.uid is the same as identity.id. Is it there to keep things consistent with other strategies (since Twitter might pass along a UID that's not tied to an actual record ID)?

Thanks for making such an awesome system!

Enable user to sign in using mobile no. or email both.

I am using email address for signing in a user. I want to enable user to sign in via both email or mobile no.

In omniauth.rb

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :identity, :fields => [:name, :email, :mobile_no], :on_failed_registration => IdentitiesController.action(:new)    
  OmniAuth.config.on_failure = Proc.new { |env|
    OmniAuth::FailureEndpoint.new(env).redirect_to_failure
  }
end

In signup form

= form_tag '/auth/identity/register', :class => 'form-stacked' do
  = text_field_tag :name, params[:name], :placeholder => 'Enter Your Name ... ', :required => true,:class=>'uneditable-input.span6'
  = text_field_tag :email,  params[:email], :placeholder => 'Enter Your Email Address ... ', :required => true ,:class=>'uneditable-input.span6'
  = text_field_tag :mobile_no,  params[:mobile_no], :placeholder => 'Enter Your Mobile No ... ', :required => true ,:class=>'uneditable-input.span6'
  = password_field_tag :password,  nil, :placeholder => 'Create Your Password ... ', :required => true ,:class=>'uneditable-input.span6'
  = password_field_tag :password_confirmation,  nil, :placeholder => 'Confirm Your Password ... ', :required => true ,:class=>'uneditable-input.span12'
    .actions style="width: 250px;"
  = submit_tag 'Sign Up', :class => 'btn btn-primary uneditable-input.span6 '

And when i recieve auth hash in session controller, mobile no is not present

env["omniauth.auth"]["info"] = #<OmniAuth::AuthHash::InfoHash email="[email protected]" name="abc">

Is there any way to signin using both email and mobile no. And also get mobile no. parameter in auth hash to save in associated user record.

Unable to use this with Sequel ORM

I'm attempting to use Omniauth-Identity with a project utilizing the Sequel ORM. Other Omniauth implementations are working fine, but when adding the Identity login, I get stuck with a constant error: undefined method 'auth_key' for Identity:Class in /gems/omniauth-identity-1.1.1/lib/omniauth/strategies/identity.rb: in block in <class:Identity>, line 13

# config.ru
use OmniAuth::Builder do
    #...other providers...
    provider :identity, :fields => [:email]
end

# classes.rb
class Identity < Sequel::Model
    plugin :secure_password
    one_to_one :account

    def validate
        super
        validates_presence [:email, :password_digest]
        validates_unique [:email]
    end
end

# migration for Identity
Sequel.migration do
    up do
        create_table(:identities) do
            primary_key :id
            foreign_key :account_id # the main user object is Account
            String :email
            String :password_digest, :text => true
        end
    end

    down do
        drop_table(:identities)
    end
end

I would really like to use this as it will ensure the user experience is the same regardless of the method they choose to authenticate, but it just isn't working.

Authentication table attributes

This is a very similar issue to #53, but the solution in that issue does not work for me.

I have used the information here https://github.com/intridea/omniauth/wiki/Managing-Multiple-Providers, to setup Identity on my application.

However the code to add the latest auth to the authentication table does not add the provider or uid attributes.

  def self.create_with_omniauth(auth)
    create(uid: auth['uid'], provider: auth['provider']) # and other data you might want from the auth hash
  end

As suggested in the older issue this might be down to mass assignment.

Is there a quick fix on how to get the uid and provider set? The auth object does contain this information.

Thanks in advance.

AuthLogic compatability?

We have an app that's currently using AuthLogic and we want to switch to Omniauth. We don't want users to have to reset their passwords after the switch. Would it be possible for us to set up Omniauth-Identity in a way that is compatible with the data stored in our DB by AuthLogic? We can reformat the tables or whatever, but obviously hashed passwords cannot be unhashed or rehashed :)

request.env['omniauth.auth'] is always nil when using seperate admin login with identity.

I want to use seperate admin login for my application using idenity provider.

I have written this in config/initializers/omniauth.rb

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :identity, :model => Credential, :on_failed_registration =>SessionsController.action(:register)
  provider :identity, :model => Credential, :name => 'admin', :on_failed_registration => SessionsController.action(:login_admin)
  provider :google_oauth2, '000000000.apps.googleusercontent.com', '00000000000'
end

In config/routes.rb

match '/auth/admin/callback', :to => 'sessions#authenticate_admin'

In app/controllers/sessions_controller.rb

def authenticate_admin
  auth_hash = request.env['omniauth.auth']
  session[:admin_user] = auth_hash['user_info']['email']
  if admin?
    redirect_to '/'
  else
    render :text => '401 Unauthorized', :status => 401
  end
end

But when i try to access request.env['omniauth.auth'], it always gets nil. While it is accessible when using default callback for normal users at sessison#create action. I just want to know if there is anything that has been missed in this code.

Integration test fails

Even if disabling OmniAuth.config.test_mode the following test fails :

require 'test_helper'
class UsersSignupTest < ActionDispatch::IntegrationTest

test "valid signup information" do   
    OmniAuth.config.test_mode = false
    get signup_path
    assert_difference 'User.count', 1 do
      get '/auth/identity/register',
        user: { name: "Example User",
                email: "[email protected]",
                password: "password",
                password_confirmation: "password" }           
    end
    assert_template 'users/show'
    OmniAuth.config.test_mode = true
end

...

I get the following

F

Failure:
UsersSignupTest#test_valid_signup_information [/home/lsoave/rails5/gitwatcher/test/integration/users_signup_test.rb:20]:
"User.count" didn't change by 1.
Expected: 4
Actual: 3

Finished in 364.229418s, 0.0055 runs/s, 0.0055 assertions/s.

2 runs, 2 assertions, 1 failures, 0 errors, 0 skips

Show invalid login error

When login fails (such as an invalid password) it currently takes the user to the failure callback of the application. I think it would be a much better user experience if mistyping a password allowed the user to stay on the login form with a nice error message saying it's invalid. Isn't this how most providers behave?

omniauth-identity "swallows" /auth/identity/callback

I'm using omniauth-identity with sinatra, and it seems that omniauth-identity swallows my callback.

The login completes fine (users can register and login), but the POST at the end of logging in is not redirected to the corresponding POST handler in my sinatra route.

If I have a route or note (i.e. no post '/auth/identity/callback' do ... end ) either way, a successful login just gets redirected to /. A failed login goes to the right error handler. I don't know where to start looking for a solution.

Raise if password_confirmation is unnecessarily needed for system actions.

To let the system continue and move on with no indication that the password was and never will be updated if a user does not send "password_confirmation" with ActiveRecord::Base#update or ActiveRecord::Base#update_attributes is pretty misleading. There should be some indication rather than nothing at all and a continued update to the database.

Confirmable and other devise features

This is more a feature request than an issue, but are there plans to include devise features such as "confirmable" or "recoverable"? I'm glad to help developing this if there's a big enough request...

Need to set password_digest when using this in conjunction with other strategies

Hi Michael,

Oddly I never really played with omniauth when I was at Intridea :) hopefully you can drop a knowledge bomb on me now though. I setup a project to use both twitter and identity and identity is of course using has_secure_password which validates the presence of password_digest on the User model which I setup as the custom class instead of Identity (ActiveRecord is what I'm using there).

I don't want to make folks that only want to use twitter for auth fill out a password when completing their registration (I have to store their omniauth info in a session and redirect to a more robust registration form populated with the data that I do have coming back from the strategy). But if I hide the password fields and submit then I get the password_digest validation error. My solution was to trigger a before validation callback and set the password_digest directly for them.

If I set it to something simple like '0' it'll pass validations and if they try to type in any password other than '0' it properly redirects to the failure action with a nice flash message. But I'm not cool with loose ends like that and if they happened to try the password of '0' outright it'll throw an invalid hash error from bcrypt. I couldn't find a way to rescue that error gracefully at the application level since it seems to be thrown from within omniauth (I think?), so to avoid the unsightly 500 I actually hash a password with a salt when saving the record. I choose the somewhat lengthy and odd "generic_identity_password" string.

Then I added a validation that wouldn't allow someone to set that as their actual password. I also wanted to handle the case where the user might somehow guess the password I set and try to login with it. So I added some controller logic to redirect the exact same way as if they had typed the password incorrectly if they guess the "generic_identity_password" string. This feels messy, but it does work. However, I'd love to refactor it to be better.

Any suggestions?

Thanks!

Callback is using HTTP GET

/auth/identity/callback is called using HTTP GET and this has a major downside, since the path is saved in browser history with cleartext password and auth_key.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.