How to use 'post' in routes.rb - ruby-on-rails

please help me
I have created a controller 'users' with a view 'login' with a form to login users, I have changed the routes.rb changing get user/login to post user/login
now when I go to localhost:3000/users/login appears:
Routing Error
No route matches [GET] "/users/login"
Try running rake routes for more information on available routes.
please what should to do to works that page, that problem is because I have changed 'get' to 'post' in the routers, there are something more that I should to add?

When you just go to that url in your browser, the type of request is GET - but, as you said, there's no route for this request now.
POST route will be useful when you actually submit a form on this page - with simple submit (specify method attribute as POST) or AJAX request.

You can use both in routes.rb:
get user/login
post user/login
This means that the controller will recognize requests made using both methods. It is up to your controller logic to sort it out. The get would typically be used to render the login form; post would receive the user's username and password, authenticate him/her, and then redirect to a page for successful login (or unsuccessful, if necessary).
I may spark some controversy by saying this but if you are a beginner and you are looking to make a "serious" web site with user authentication, you may not want to leave anything up to chance and instead use a gem like devise (https://github.com/plataformatec/devise) to do it for you. Some will say that it's better to learn how to do it from scratch first, and there's some sense in that, too.

Related

Log out of app with cURL

We have a web app built in Ruby on Rails that uses Devise for logging in and out. I'm responsible for a backend XML API using cURL. Users can log in, send updates, etc. at a command prompt with cURL and XML strings, but I don't see how to allow them to log off with a cURL command.
The UI has a logout link that sends a DELETE command, but it uses an authenticity_token parameter that I'm not sure how to emulate or pass through cURL. The output from rake routes shows destroy_user_session as a DELETE action sent to devise, and I've tried using cURL just to point to its path, but that doesn't seem to do anything.
Most of the related resources I've found seem specific to php or to slightly different scenarios.
Edit: Would it be easier to create a new controller action to handle this, so the user just puts in the correct path, and the actual DELETE/POST/whatever is handled in code?
If you not particular about the delete attribute being present. You can configure in devise to log out via post or get.
in the config/initializers/devise.rb you will find
config.sign_out_via = :delete
change that to
config.sign_out_via = :get
Now you should be able to log_out by sending a curl request to the the logout url.
Though my personal suggestion is to authenticate the XML API using key rather than login in using the username and password.
This article should help you get started. http://blog.joshsoftware.com/2011/12/23/designing-rails-api-using-rabl-and-devise/

Rails + Devise + API + User Registration

I am new to ruby and rails and so far I managed to setup user management using devise. Right now I am trying to integrate support for mobile Android and iOS apps. So far it is possible for them to login and logout and get an authentication token. But in addition to that I would also like them to be able to register.
Now, as I understand it I have to do a post to
http://localhost:3000/users/sign_up
How does this post look like? And how do I get a JSON response? I found this on stackoverflow.
"utf8=✓&authenticity_token=n5vXMnlzrXefnKQEV4SmVM8cFdHDCUxMYWEBMHp9fDw%3D&user[email]=asd%40fasd.org&user[password]=321&user[password_confirmation]=1233&commit=Sign+up"
Unfortunately this does not work - I am getting the message "Bad request". I also do have a couple of questions about this example. What is the authenticity_token for? How do I get one? This is not the devise token authentication I guess as the user is not even in a position to have one at this point.
Also, after a successful login I would like to bundle the "registration successful" message with a generated devise authentication token. So I guess I have to somehow extend devise`s existing registration controller.
Thank you very much in advance!
Devise already has all this setup. Based on your signup path, I infer that you mounted Devise onto http://localhost:3000/users. Devise includes all the controllers and views that are required, including the log in form, the sign up form, the email confirmation form and the password reset forms.
GET http://localhost:3000/users/sign_up is actually a form for users to signup at. The form on that page will POST to http://localhost:3000/users/, which goes to Devise's registration controller's create action.
Assuming there is no action/view already at /users/sign_up, the sign up form should be there, go check if it is there (assuming you set up devise_for correctly in your routes.rb file).

Routing and Forms for a Rails app authentication system

I am having trouble understanding how to craft a Rails application that follows the following scheme:
The site is composed primarily of 'protected' interior paths which require the user be authenticated, in addition to one or two unprotected 'static' pages and a login page served directly from '/' (root_path).
I want users to generally follow the flow that they log in by going to root_path, and any attempt to access a protected page while unauthenticated sends them back to root_path. When the user logs in on the form in root_path, they get sent to home_path (even if they had been sent to root_path via some other page's protection - ie., no smart forwarding. I may add that later.)
Additionally, trying to browse to root_path while already authenticated should immediately forward the request to home_path. home_path's page will include a link to log out, the effect of which should immediately send the user to root_path.
My question:
What would the routes.rb entries look like to set this up? Assuming I have a Users controller and a Sessions controller, and assuming that I already have command-line authentication (via the irb console) working, what is the correct combination of routes and controller methods that gets this system working? I'm very confused!
In case it helps, here is what I have so far, but I'm so lost that I can't even get this in to a working state to test it.
I have a routes file that looks like:
MyAppRails::Application.routes.draw do
resources :sessions, only: [:new, :create, :destroy]
root to: "sessions#new"
match '/signout', to: 'sessions#destroy', via: :delete
match "/home" => 'users#home'
end
The UsersController only has a home method, and the SessionsController has new, create, and destroy methods.
I'm particularly stuck in that I don't know where to send the sign-in form to - I figure it should point at sessions#new somehow but I don't really get how that works.
Thanks.
You shouldn't need to change your routes, as a before_filter should be placed in each controller where you want to restrict access to logged in users. A :login_required method could be called to check if a user is logged in, otherwise, redirect them to your public page.
Generally, I keep the root as a separate controller, site_controller, or something similar. I also make my login path sessions#new and use my before_filter methods to manage redirecting guests that haven't logged in.
This thread may help you.

Rails POST doesnt extract any path, query or request parameters

I want to grant users access to my API (hosted on heroku.com) from their sites.
But a strange problem occurs, when i want them to allow to post to the api:
Data sent from an correct form with the correct action-url (e.g. "http://myapp.com/projects/123/tasks/321/todos") - the params get serialized and send via jQuery - i encounter an "ActionController::MethodNotAllowed" with the additional info: "Only get and post requests are allowed", that re-routes to ApplicationController#index with :method => :options.
Rails doesnt extract the params for project_id (123) and task_id (321) from the url, neither are any further request_parameters, path_parameters or query_parameters available.
This behaviour occurs, when I POST from external sites, but doesn't occur, when posting from an html-page on my local machine. My first thought was about wrong encoding, but how to fix that problem.
Edit:
I am using authlogic (not devise :-D) and for the :create action the protect_from_forgery is already skipped.
Any suggestions appreciated
i guess that happens because rails tries to protect your form CSRF attacks.
you can comment out the protect_from_forgery line in your ApplicationController to test it.
but im not sure if thats the right way of dealing with this issue in the production environment.
Okay. I'll try and answer the right question this time (see other comment).
So I've thought about this, and I'm wondering, is this a case of the jQuery call attempting a PUT request? When you use the local form Rails will POST the data, but add the extra _method field to emulate a PUT.
Don't know if you are using jquery-rails, but this takes care of setting the _method parameter, and the PUT/POST verb translation for you in your AJAX calls.
The problem occured due to the cross domain policy - the request was made from another domain - and because I was using a recent browser that supports CORS, it was sending an OPTIONS-request first to get known from the server, which actions are allowed for this domain.

How do you pass a POST method in a url manually?

I need to give an external payment site a return url to my site after a customer pays. It will be to my create action in a RESTful subscription controller.
Ive tried giving the payment site this
blah.com/users/7/subscription/?_method=POST
but on return my app keeps trying to call my show action presumably because it thinks its a get request and not a post. So somethings wrong with how i pass the method in the url but i cant figure out what.
Users are plural and they can only have one subscription which is defined in my routes as singular i.e. map.resource
Can anyone help?
You can't POST from a GET request.
If the calling application is simply executing a URL this is a GET request.
If the payment site does not support POSTing back to you then you can't do it.
I would ask the payment site if they offer the ability to POST to you. Many do.
If the external service isn't calling your url with a POST, then it is an issue with that service, not your application. Also, keep in mind that CSRF will protect your POST, PUT, DELETE without a token, so you'll need to disable it for this method, and hopefully you have some other way of authenticating that request.

Resources