I created a demo authentication application in rails using Devise gem. I created a sessions controller to sign in a user. But when I'm sending a request localhost:3000/api/v1/sessions/
using postman to the session controller I'm getting the following error :
"Could not find a valid mapping for #<User id: 2, email: "smith@railsapi.com", encrypted_password: "$2a$10$J5lCfQzWsxvjsXe.3EXfZ.ST9nztLLW8fhqYgXNtJP1...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2016-03-26 03:59:22", updated_at: "2016-03-26 03:59:22", auth_token: "_D3GU1TftgP7YHNcRftN">"
Here's my model users.rb
class User < ActiveRecord::Base
before_create :generate_authentication_token!
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
validates :auth_token, uniqueness: true
def generate_authentication_token!
begin
self.auth_token = Devise.friendly_token
end while self.class.exists?(auth_token: auth_token)
end
end
Here's my sessions controller
class Api::V1::SessionsController < ApplicationController
def create
user_password = params[:session][:password]
user_email = params[:session][:email]
puts user_password
puts user_email
user = user_email.present? && User.find_by(email: user_email)
if user.valid_password? user_password
sign_in user, store: false
user.generate_authentication_token!
user.save
render json: user, status: 200
else
render json: { errors: "Invalid email or password" }, status: 422
end
end
end
And My routes.rb file :
Rails.application.routes.draw do
# API routes path
namespace :api, defaults: { format: :json } do
namespace :v1 do
resources :users, only: [:show, :create, :update]
resources :sessions, only:[:create, :destroy]
end
end
end
Application.rb
require File.expand_path('../boot', __FILE__)
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module DemoApi
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
# Do not swallow errors in after_commit/after_rollback callbacks.
config.active_record.raise_in_transactional_callbacks = true
DeviseController.respond_to :html, :json
end
end
I would really appreciate if someone can tell me where I'm going wrong. Thanks
A better and easy way to solve this problem is using devise with devise_token_auth gem to accomplish the JWT(JSON Web Token) authentication system. This gem will give you all the tools you need to create a JWS system. We had a talk about API Authentication in my town and I created a basic app using this feature. I will describe how I have implemented the solution here, but fell free to check it out the Sample Repo here . It is an Instagram-like app.
Step 1: Add to your Gemfile:
gem 'devise_token_auth'
Install the gem
$ bundle install
step 2 : generate the configurations needed by the gem
$ rails generate devise_token_auth:install User auth
$ bundle exec rake db:migrate
It will generate a migration file that adds a couple of new attributes to your user model, but basically the main line is that:
## Tokens
t.text :tokens
It will provide an array of tokens that will be kept in the database for user authentication
It also adds the routes for authentication/sign_in/sign_up
mount_devise_token_auth_for "User", at: 'auth'
step 3: lookup for the routes
Now, on your terminal, execute:
$ rake routes
It will show the routes for authentication , sign in and sign_up
step 4: Using postman to try it out
As you mentioned, using the Postman, you now can send a POST to localhost:3000/auth/ with email , password , and password_confirmation (those fields are required) to register the user. (Check the devise_token_auth README to see how to sign_in and sign_out ).
The key here is that registration request and sign_in request will return the response with many headers(if the status code was OK) that contains all the authentication information you need. You have to extract those headers on your mobile client(or even using postman to test the authentication required routes) and add to all further requests that require authentication in your app.
Try to do that, clone and check the Sample Repo that I pointed out and see if you get it done. Let me know if you got it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.