I have tried everithing starting following this guide
https://adibsaad.com/blog/setting-up-ember-cli-with-a-rails-back-end-and-token-authentication-authorization
but still it does not work. When I try to reach pages that are protected with authentication token the server give me "unauthorized 401". Here
https://github.com/francescabarbazeni87/Ember-Devise-Simple-Auth-Example-
there is my code for the server and client side. Many thanks in advance.
class ApplicationController < ActionController::Base
before_filter :authenticate_user_from_token!
# Enter the normal Devise authentication path,
# using the token authenticated user if available
#before_filter :authenticate_user! <-----you dont need this line...delete or comment it out
Related
If I set the following code on my mainapp/config/routes.rb, all routes will require authentication and I will not be able to use before_action :authenticate_user!, except: [:mypublic_method] in my controller.
Rails.application.routes.draw do
devise_for :users
authenticate :user do
mount Myengine::Engine, at: '/myengine'
end
end
Rails seems to need the mounted routes to be able to see the engine through URLs.
If I set the following code on my mainapp/config/routes.rb, all routes will be public, but I want to make pulbic only the methods that I wish.
Rails.application.routes.draw do
devise_for :users
mount Myengine::Engine, at: '/myengine'
end
What can I do to make public/accessible mypublic_method (vendor/engines/myengine/app/controllers/myengine/mycontroller_controller.rb) using authenticate :user?
p.s. the same question in another way How can I avoid Devise from requires authentication from within an engine?
ruby 2.2.3p173
Rails 4.2.5
Devise 3.5.3
Thank you.
I solved the problem, this was simple. Now I'm doing the authentication in my Engine Application Controller, not by routes on my Main Application Controller.
module Myengine
class ApplicationController < ActionController::Base
before_action :authenticate_user!
end
end
I also removed authenticate :user on my config/routes.rb (main application)
mount Myengine::Engine, at: '/myengine'
That way I'm able to use the following code in any controller
before_action :authenticate_user!, except: [:mypublic_method]
I have a rails(4.2.0) application that uses Facebook login functionality. The main gems are devise(3.4.0) and omniauth-facebook(2.0.0). I have registered the application on Facebook and have been using its test app for development. The Facebook login functionality works in the development env.
When trying to use the facebook login feature on the production server, I get error as "Given URL is not allowed by the Application configuration: One or more of the given URLs is not allowed by the App's settings. It must match the Website URL or Canvas URL, or the domain must be a subdomain of one of the App's domains."
The details for settings for test app being used in the dev env are as -
Settings:
Basic:
App Domains: 'localhost'
Website:
Site URL: 'http://localhost:3000'
Advanced:
OAuth Settings:
Embedded browser OAuth Login: Yes
Valid OAuth redirect URIs: "http://localhost:3000/users/auth/facebook/callback"
The details for settings for registered app being used in the production env are as -
Settings:
Basic:
App Domains: 'www.mysite.co'
Website:
Site URL: 'http://www.mysite.co'
Advanced:
OAuth Settings:
Embedded browser OAuth Login: Yes
Valid OAuth redirect URIs: "http://www.mysite.co/users/auth/facebook/callback"
I have specified the following in my secrets.yml
development:
secret_key_base: some_secret_key
facebook:
app_id: test_app_id
app_secret: test_app_secret
production:
secret_key_base: some_secret_key
facebook:
app_id: registered_app_id
app_secret: registered_app_secret
And have been using the creds from secrets.yml in the devise initialiser as
# ==> OmniAuth
# Add a new OmniAuth provider. Check the wiki for more information on setting
# up on your models and hooks.
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
require 'omniauth-facebook'
config.omniauth :facebook, Rails.application.secrets.facebook['app_id'], Rails.application.secrets.facebook['app_secret'], scope: ['user_photos', 'email', 'public_profile']
The actual domain name(blackened) has no typos anywhere and is same wherever it is used.
Contains of routes.rb related to omniauth are as
cat config/routes.rb
Rails.application.routes.draw do
root 'home#index'
devise_for :users, controllers: { omniauth_callbacks: "users/omniauth_callbacks" }
# routes related to other controllers
end
The routes are as below
bundle exec rake routes | grep user
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_omniauth_authorize GET|POST /users/auth/:provider(.:format) users/omniauth_callbacks#passthru {:provider=>/facebook/}
user_omniauth_callback GET|POST /users/auth/:action/callback(.:format) users/omniauth_callbacks#:action
The only code related to omniauth in the entire app is as
$ cat app/controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
#You need to implement the method below in your model (e.g. app/models/user.rb)
#user = User.from_omniauth(request.env["omniauth.auth"])
if #user.persisted?
sign_in_and_redirect #user, event: :authentication #this will throw if #user is not activated
set_flash_message(:notice, :success, kind: "Facebook") if is_navigational_format?
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
end
Upon further digging the problem, it was observed that the error didnt occur when 'www.example.com' was specified in the url and hence, the callback worked. When 'example.com' was specified in the address bar and facebook login tried, the login crashed with the above error.
So, I fixed the above issue by making some changes to the settings in for the facebook app. I donno if this is the right approach but it worked out. Just making the change as in point 2 didnt solve the problem.
Changes are:
1) Specified the 'App Domains' with 'example.com' and 'www.example.com'
2) Enabled 'Client OAuth Login' to 'Yes'
3) Specified 'Valid OAuth redirect URIs' with 'http://example.com/users/auth/facebook/callback' and 'http://www.example.com/users/auth/facebook/callback'
Ok, so I assume that you have a web app NOT running on Facebook that simply uses the Facebook OAuth flow for login functionality, correct? If so, you must enable "Client OAuth Login" in your application settings for the production environment. If you don't, then the web OAuth flow will not work. See this article: https://developers.facebook.com/docs/facebook-login/security
I want a password site wide just like Rack's Basic AUTH
/config.ru
use Rack::Auth::Basic, "Restricted Area" do |username, password|
[username, password] == ['admin', 'admin']
end
run Rails.application
But I don't want it to block paths /API and /mailgun/incoming_email with password access. Can I accomplish this in Rack? Or should I implement a scope within the routes.rb that almost all resources are behind a Rack (enter once) password?
For the record I am using Devise within the site... that's separate. I need a sitewide password before it.
[Revised Question]
Specific Routes
I would like to password protect only the root path / and /visitors with the Rack like password. I've seen something used in a Rails routes.rb file before with a lambda condition requiring the password. I'm not having luck finding that information at the moment.
My website already redirects unauthenticated Devise users to /users/sign_in. So I only needed to password protect /, /users/sign_in, and /users/sign_up. This is how I did it.
config.ru
class RootSiteAuth < Rack::Auth::Basic
def call(env)
request = Rack::Request.new(env)
if ['/', '/users/sign_in', '/users/sign_up'].include? request.path
super
else
#app.call(env)
end
end
end
use RootSiteAuth, "Restricted Area" do |username, password|
[username, password] == ['admin', 'admin']
end
run Rails.application
And it works. Every controller that has before_filter :authenticate_user! redirects to the Rack password page. After authentication we're good to go. Anything without the filter permits outside access as planned. ^_^
I'm writing an API aside with an web page. I want to have Oauth2 login so i can keep a session from the mobile device, i've already install the GEM doorkeeper and run the migration how it's explained on this site.
where i'm getting stuck is in the resource_owner_from_credentials parts, since i have an User model which has authenticate method given by the has_secure_password helper from rails. this is how my /config/initializers/doorkeeper.rb file looks like
Doorkeeper.configure do
# Change the ORM that doorkeeper will use.
# Currently supported options are :active_record, :mongoid2, :mongoid3, :mongo_mapper
orm :active_record
# This block will be called to check whether the resource owner is authenticated or not.
resource_owner_from_credentials do
User.find_by_email(params[:email]).authenticate(params[:password])
end
##lots of comments
end
and when go to
localhost:3000/oauth/authorize
i get this:
config/initializers/doorkeeper.rb:8:in `block (2 levels) in <top (required)>'
then i tried:
http://127.0.0.1:3000/oauth/authorize?email=puca#gmail.com&password=porche
and the same
what i'm i doing wrong? how should i configuresource_owner_authenticator block? how do i get the token?
As per this doorkeeper wiki page you need to send a POST request to /oauth/token API with the following params:
{
"grant_type" : "password",
"username" : "user#example.com",
"password" : "sekret"
}
When this request is processed, doorkeeper calls the resource_owner_from_credentials block and passes the params to it. So you have access to the param named username and not email.
To summarize, fix the API endpoint to /oauth/token , change params[:email] to params[:username] and everything should work.
I want foo.com/ to show the landing page when the user isn't logged in, and foo.com/ to show the dashboard of the user when the user is logged in, just like in Facebook.
I was going to do it the following way:
def index
if user_signed_in?
#posts = current_user.posts
render 'home/dashboard'
else
render 'home/landing'
end
end
But then quickly realized that I'd need to use before_filter :authenticate_user! in order to get current_user, so Devise will require to sign in.
Maybe there's a way to do this more cleanly using routing. Please advice.
authenticated :user do
root to: "users#index", as: :authenticated_root
end
unauthenticated do
root to: "main#index"
end
https://github.com/plataformatec/devise/issues/2393#issuecomment-17298414