Ale*_*eña 6 api ruby-on-rails user-registration devise
我正在尝试为我的rails应用程序设置用户注册端点,以便我可以在iOS再现中访问应用程序功能.我已经开始将命名空间命名为API,到目前为止已经设法使用Devise和JWT进行用户身份验证.
这很棒,但我还需要能够通过API注册用户.坦率地说,我不知道如何正确实现这一点.几个GOogle文章要么提出过时的文章,使用已弃用的令牌可验证,要么从未得到过回答.
以下是我认为与此问题最相关的代码:
namespace :api do
namespace :v1 do
devise_for :users, controllers: { registrations: 'api/v1/registrations' }
resources :classrooms
resources :notifications
end
end
end
Run Code Online (Sandbox Code Playgroud)
class Api::V1::RegistrationsController < Devise::RegistrationsController
respond_to :json
def create
if params[:email].nil?
render :status => 400,
:json => {:message => 'User request must contain the user email.'}
return
elsif params[:password].nil?
render :status => 400,
:json => {:message => 'User request must contain the user password.'}
return
end
if params[:email]
duplicate_user = User.find_by_email(params[:email])
unless duplicate_user.nil?
render :status => 409,
:json => {:message => 'Duplicate email. A user already exists with that email address.'}
return
end
end
@user = User.create(user_params)
if @user.save!
render :json => {:user => @user}
else
render :status => 400,
:json => {:message => @user.errors.full_messages}
end
end
private
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute, :first_name, :last_name, :access_code])
end
end
Run Code Online (Sandbox Code Playgroud)
http://localhost:3000/api/v1/users
{
"message": [
"Email can't be blank",
"Password can't be blank",
"Access code is invalid [Beta]."
]
}
Run Code Online (Sandbox Code Playgroud)
我将非常感激任何帮助,因为我渴望学习更多(并让它发挥作用!).
这是我在发出生成用户的帖子请求后在服务器上得到的内容......
Started POST "/api/v1/users" for 127.0.0.1 at 2017-02-22 09:22:11 -0800
Processing by Api::V1::RegistrationsController#create as */*
Parameters: {"user"=>{"email"=>"user@sampleapi.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "access_code"=>"uiux"}}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."email" IS NULL LIMIT $1 [["LIMIT", 1]]
Completed 400 Bad Request in 2ms (Views: 0.2ms | ActiveRecord: 0.4ms)
Run Code Online (Sandbox Code Playgroud)
class Api::V1::RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: [:create]
respond_to :json
def create
@user = build_resource(sign_up_params)
if @user.persisted?
# We know that the user has been persisted to the database, so now we can create our empty profile
if resource.active_for_authentication?
sign_up(:user, @user)
render :json => {:user => @user}
else
expire_data_after_sign_in!
render :json => {:message => 'signed_up_but_#{@user.inactive_message}'}
end
else
if params[:user][:email].nil?
render :status => 400,
:json => {:message => 'User request must contain the user email.'}
return
elsif params[:user][:password].nil?
render :status => 400,
:json => {:message => 'User request must contain the user password.'}
return
end
if params[:user][:email]
duplicate_user = User.find_by_email(params[:email])
unless duplicate_user.nil?
render :status => 409,
:json => {:message => 'Duplicate email. A user already exists with that email address.'}
return
end
end
render :status => 400,
:json => {:message => resource.errors.full_messages}
end
end
protected
# If you have extra params to permit, append them to the sanitizer.
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute, :first_name, :last_name, :access_code])
end
end
Run Code Online (Sandbox Code Playgroud)
我很确定我此时的主要问题是我的参数的格式,因此任何正确方向的推动都会很棒.我确实找到了这篇文章,但我发现它有点难以理解它们的API工作原理......
小智 6
这里有 2 种解决方案,请选择您喜欢的一种。
覆盖 devise_parameter_sanitizer:
class ApplicationController < ActionController::Base
protected
def devise_parameter_sanitizer
if resource_class == User
User::ParameterSanitizer.new(User, :user, params)
else
super # Use the default one
end
end
end
Run Code Online (Sandbox Code Playgroud)覆盖 sign_up_params:
def sign_up_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
Run Code Online (Sandbox Code Playgroud)如果您深入研究Devise ParameterSanitizer,则 resource_name 将是:api_v1_user,而不仅仅是:user因为您的路线:
namespace :api do
namespace :v1 do
devise_for :users, controllers: { registrations: 'api/v1/registrations' }
end
end
Run Code Online (Sandbox Code Playgroud)
错误资源名称将导致sign_up_params始终返回空哈希{}
为什么不使用simple_token_authentication gem ?
设置极其简单:
# Gemfile
gem "simple_token_authentication"
bundle install
rails g migration AddTokenToUsers "authentication_token:string{30}:uniq"
rails db:migrate
# app/models/user.rb
class User < ApplicationRecord
acts_as_token_authenticatable
# [...]
end
Run Code Online (Sandbox Code Playgroud)
在您的路线中:
# config/routes.rb
Rails.application.routes.draw do
# [...]
namespace :api, defaults: { format: :json } do
namespace :v1 do
resources :classrooms
resources :notifications
end
end
end
Run Code Online (Sandbox Code Playgroud)
在你的控制器中:
# app/controllers/api/v1/classrooms_controller.rb
class Api::V1::ClassroomsController < Api::V1::BaseController
acts_as_token_authentication_handler_for User
# [...]
end
Run Code Online (Sandbox Code Playgroud)
使用 RestClient gem 的示例调用:
url = "http://localhost:3000/api/v1/classrooms/"
params = {user_email: 'john@doe.com', user_token: '5yx-APbH2cmb11p69UiV'}
request = RestClient.get url, :params => params
Run Code Online (Sandbox Code Playgroud)
对于没有令牌的现有用户:
user = User.find_by_email("john@doe.com")
user.save
user.reload.authentication_token
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4994 次 |
| 最近记录: |