有人可以帮我弄清楚如何使用rails中的设计正确访问经过身份验证的路由吗?我已经弄清楚如何验证会话并获取令牌,但是当我在经过身份验证的路由中传递该令牌时,我收到有关需要登录的错误。这可能是一个卷曲格式问题,但我是rails的新手,我不太清楚该怎么做。
我可以传递curl命令并获取正确的令牌:
curl -X POST 'http://localhost:3000/users/sign_in.json' -d 'user[email]=user@name.com&user[password]=password'
我回来了:
{"token":"at6aig30jzulnnyomrm4c5","user_email":"user@name.com"}
问题在于,当我尝试访问用户的路由时,我收到了一个拒绝权限错误:
curl -L 'http://localhost:3000/users/me.json?token=at6aig30jzulnnyomrm4c5'
{"error":"You need to sign in or sign up before continuing."}
我的路线看起来像这样:
devise_for :users, controllers: { sessions: 'sessions' }, :skip => [:passwords]
resources :users, only: [:create, :update] do
get 'me' => 'users#me', on: :collection
end
相应的路线如下所示:
new_user_session GET /users/sign_in(.:format) sessions#new
user_session POST /users/sign_in(.:format) sessions#create
destroy_user_session DELETE /users/sign_out(.:format) sessions#destroy
me_users GET /users/me(.:format) users#me
users POST /users(.:format) users#create
user PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
我的用户控制器如下所示:
class UsersController < ApplicationController
before_action :authenticate_user!, except: [:create, :start_password_reset, :finish_password_reset]
before_action :assert_reset_token_passed, only: [:finish_password_reset]
def create
user = User.new(register_params)
if user.save
render json: user, status: :created
else
render json: { errors: user.errors.full_messages }, status: :unprocessable_entity
end
end
def update
if current_user.update(user_params)
render json: current_user
else
render json: { errors: current_user.errors.full_messages }, status: :unprocessable_entity
end
end
def me
if current_user
render json: current_user, status: 200
else
render json: {}, status: 400
end
end
def start_password_reset
user = User.where(email: params[:email]).first
user.send_reset_password_instructions if user
render json: {}
end
def finish_password_reset
user = User.with_reset_password_token(params[:reset_password_token])
if user
if user.reset_password!(reset_params[:password], reset_params[:password_confirmation])
render json: {}
else
render json: { errors: user.errors.full_messages }, status: 400
end
else
render json: { errors: ['Invalid password reset request.'] }, status: 403
end
end
private
def register_params
params.require(:user).permit(:email, :password, :time_zone)
end
def user_params
params.require(:user).permit(:include_email_memory, :time_zone, email_times: [:monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday])
end
def reset_params
params.permit(:password, :password_confirmation)
end
# Check if a reset_password_token is provided in the request
def assert_reset_token_passed
render(json: { errors: ['Invalid password reset request.'] }, status: 403) if params[:reset_password_token].blank?
end
end
对于它的价值,我正在尝试使用Ember simple-auth,这样我就可以正确加载用户的个人资料。谢谢您的帮助!
编辑:根据要求,这是我的应用程序控制器:
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :null_session
skip_before_filter :verify_authenticity_token
before_filter :authenticate_user_from_token!
#before_filter :authenticate_user!
around_action :user_time_zone, if: :current_user
def index
render file: 'public/index.html'
end
protected
# def authenticate_user!
# render(json: {}, status: 401) unless current_user
# end
private
def authenticate_user_from_token!
authenticate_with_http_token do |token, options|
user_email = options[:user_email].presence
user = user_email && User.find_by_email(user_email)
if user && Devise.secure_compare(user.authentication_token, token)
sign_in user, store: false
end
end
end
def user_time_zone(&block)
Time.use_zone(current_user.time_zone, &block)
end
# If this is a get request for HTML, just render the ember app.
def handle_html
render 'public/index.html' if request.method == 'GET' && request.headers['Accept'].match(/html/)
end
end
答案 0 :(得分:1)
您只在请求中包含token
curl -L 'http://localhost:3000/users/me.json?token=at6aig30jzulnnyomrm4c5'
但您的服务器也希望传递电子邮件:
authenticate_with_http_token do |token, options|
user_email = options[:user_email].presence
user = user_email && User.find_by_email(user_email)
…